win32DirectoryResolver.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include <windowsx.h>
  23. #include <shlobj.h>
  24. #include <shlwapi.h>
  25. #include "string/unicode.h"
  26. #include "console/consoleTypes.h"
  27. #include "win32DirectoryResolver.h"
  28. //-----------------------------------------------------------------------------
  29. Win32DirectoryResolver::Win32DirectoryResolver() : mPSL(0), mPPF(0)
  30. {
  31. // COM init
  32. CoInitialize(NULL);
  33. // Get a pointer to the IShellLink interface.
  34. HRESULT hres = CoCreateInstance( CLSID_ShellLink,
  35. NULL,
  36. CLSCTX_INPROC_SERVER,
  37. IID_IShellLink,
  38. (LPVOID*) &mPSL );
  39. // Get a pointer to the IPersistFile interface.
  40. if( SUCCEEDED( hres ) )
  41. mPSL->QueryInterface( IID_IPersistFile, (LPVOID*)&mPPF );
  42. }
  43. //-----------------------------------------------------------------------------
  44. Win32DirectoryResolver::~Win32DirectoryResolver()
  45. {
  46. // COM clean up
  47. if( mPPF )
  48. {
  49. mPPF->Release();
  50. mPPF = 0;
  51. }
  52. if( mPSL )
  53. {
  54. mPSL->Release();
  55. mPSL = 0;
  56. }
  57. CoUninitialize();
  58. }
  59. //-----------------------------------------------------------------------------
  60. bool Win32DirectoryResolver::isDirectory( LPSTR strPathName ) const
  61. {
  62. // Normal directory?
  63. if( PathIsDirectoryA( strPathName ) )
  64. return true;
  65. // Check if it is a shortcut and if so check if it is to a directory
  66. // Does it have a file extension?
  67. const char *pathEnd = strPathName + dStrlen( strPathName );
  68. if( PathFindExtensionA( strPathName ) != pathEnd )
  69. return false;
  70. // Ok, so it could be a short cut
  71. bool result = false;
  72. // Make sure we have the interfaces we need
  73. if( mPSL && mPPF )
  74. {
  75. // COM stuff need UTF16/WCHAR
  76. UTF16 wpath[ MAX_PATH ];
  77. convertUTF8toUTF16( strPathName, wpath, sizeof(wpath) );
  78. if( !PathAddExtensionW( wpath, L".lnk" ) )
  79. return false;
  80. // Load the shortcut
  81. HRESULT hres = mPPF->Load( wpath, STGM_READ );
  82. if( SUCCEEDED( hres ) )
  83. {
  84. // Resolve the link
  85. hres = mPSL->Resolve( 0, SLR_ANY_MATCH );
  86. if( SUCCEEDED( hres ) )
  87. {
  88. // Get the path to the link target (reuse buffer)
  89. WIN32_FIND_DATA wfd;
  90. hres = mPSL->GetPath( wpath,
  91. sizeof(wpath),
  92. (WIN32_FIND_DATA *)&wfd,
  93. SLGP_SHORTPATH );
  94. // Is it a directory?
  95. if( SUCCEEDED( hres ) )
  96. result = PathIsDirectory( wpath );
  97. }
  98. }
  99. }
  100. return result;
  101. }
  102. //-----------------------------------------------------------------------------
  103. /*
  104. bool Win32DirectoryResolver::isDirectory( LPSTR strPathName ) const
  105. {
  106. // Normal directory?
  107. if( PathIsDirectoryA( strPathName ) )
  108. return TRUE;
  109. // Check if it is a shortcut and if so check if it is to a directory
  110. // Does it have a file extension?
  111. //if( PathHas
  112. // No so it could be a short cut
  113. bool result = false;
  114. char shortCutPath[ MAX_PATH ];
  115. dStrcpy( shortCutPath, strPathName );
  116. dStrcat( shortCutPath, ".lnk" );
  117. // Get a pointer to the IShellLink interface.
  118. IShellLink* psl;
  119. HRESULT hres = CoCreateInstance( CLSID_ShellLink,
  120. NULL,
  121. CLSCTX_INPROC_SERVER,
  122. IID_IShellLink,
  123. (LPVOID*) &psl );
  124. if( SUCCEEDED( hres ) )
  125. {
  126. // Get a pointer to the IPersistFile interface.
  127. IPersistFile* ppf;
  128. hres = psl->QueryInterface( IID_IPersistFile, (LPVOID*)&ppf );
  129. if( SUCCEEDED( hres ) )
  130. {
  131. WORD wsz[MAX_PATH];
  132. // Ensure that the string is Unicode.
  133. MultiByteToWideChar( CP_ACP,
  134. 0,
  135. shortCutPath,
  136. -1,
  137. wsz,
  138. MAX_PATH );
  139. // Load the shortcut.
  140. hres = ppf->Load( wsz, STGM_READ );
  141. if( SUCCEEDED( hres ) )
  142. {
  143. // Resolve the link.
  144. hres = psl->Resolve( 0, SLR_ANY_MATCH );
  145. if( SUCCEEDED( hres ) )
  146. {
  147. WIN32_FIND_DATA wfd;
  148. WCHAR szGotPath[ MAX_PATH ];
  149. // Get the path to the link target.
  150. hres = psl->GetPath( szGotPath,
  151. MAX_PATH,
  152. (WIN32_FIND_DATA *)&wfd,
  153. SLGP_SHORTPATH );
  154. if( SUCCEEDED( hres ) )
  155. result = PathIsDirectory( szGotPath );
  156. }
  157. }
  158. // Release the pointer to the IPersistFile interface.
  159. ppf->Release();
  160. }
  161. // Release the pointer to the IShellLink interface.
  162. psl->Release();
  163. }
  164. // whether OS is <= NT4 or not... use this helper:
  165. //if( ShortToLongPathName( LnkPath, sLong ) > LnkPath.GetLength() )
  166. // LnkPath = sLong;
  167. return result;
  168. }*/
  169. //-----------------------------------------------------------------------------