Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
8.0 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name :
  4. urlscan.cpp
  5. Abstract:
  6. Replace Dll, and retrieve URLScan Path
  7. Author:
  8. Christopher Achille (cachille)
  9. Project:
  10. URLScan Update
  11. Revision History:
  12. March 2002: Created
  13. --*/
  14. #include "stdafx.h"
  15. #include "windows.h"
  16. #include "urlscan.h"
  17. #include "updateini.h"
  18. #include "service.h"
  19. #include "resource.h"
  20. #include <ole2.h>
  21. #include "initguid.h"
  22. #include <coguid.h>
  23. #include "iadmw.h"
  24. #include "iiscnfg.h"
  25. // GetUrlScanPath
  26. //
  27. // Get the path to URLScan
  28. //
  29. // Parameters:
  30. // pAdminBase - [in] Pointer to AdminBase Class
  31. // szPath - [out] Path to urlscan
  32. // dwCharsinBuff - [in] Size of buffer
  33. BOOL
  34. GetUrlScanPath( IMSAdminBase *pAdminBase, LPTSTR szPath, DWORD dwCharsinBuff )
  35. {
  36. METADATA_RECORD mdrData;
  37. DWORD dwRequiredSize;
  38. BOOL bRet = TRUE;
  39. mdrData.dwMDIdentifier = MD_FILTER_IMAGE_PATH;
  40. mdrData.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  41. mdrData.dwMDUserType = IIS_MD_UT_SERVER;
  42. mdrData.dwMDDataType = STRING_METADATA;
  43. mdrData.dwMDDataLen = ( dwCharsinBuff * sizeof( TCHAR ) );
  44. mdrData.pbMDData = (UCHAR *) szPath;
  45. if ( FAILED( pAdminBase->GetData( METADATA_MASTER_ROOT_HANDLE,
  46. METABASE_URLSCANFILT_LOC,
  47. &mdrData,
  48. &dwRequiredSize ) ) )
  49. {
  50. bRet = FALSE;
  51. }
  52. return bRet;
  53. }
  54. // IsURLScanInstalled
  55. //
  56. // Determine if URLScan is installed.
  57. //
  58. // Parameters:
  59. // szPath - The path to where URLScan is installed
  60. //
  61. // Return:
  62. // TRUE - Yes, it is installed, and szPath points to it
  63. // FALSE - It is not installed as a global filter
  64. //
  65. BOOL
  66. IsUrlScanInstalled( LPTSTR szPath, DWORD dwCharsinBuff )
  67. {
  68. HRESULT hRes;
  69. IMSAdminBase *pAdminBase = NULL;
  70. IClassFactory *pcsfFactory = NULL;
  71. if ( FAILED( CoInitializeEx(NULL, COINIT_MULTITHREADED) ) )
  72. {
  73. // Could not initialize COM
  74. return FALSE;
  75. }
  76. hRes = CoGetClassObject( GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
  77. if ( SUCCEEDED(hRes) )
  78. {
  79. hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &pAdminBase);
  80. pcsfFactory->Release();
  81. }
  82. if ( SUCCEEDED(hRes) )
  83. {
  84. if ( !GetUrlScanPath( pAdminBase, szPath, dwCharsinBuff ) )
  85. {
  86. hRes = E_FAIL;
  87. }
  88. }
  89. if ( pAdminBase )
  90. {
  91. pAdminBase->Release();
  92. }
  93. CoUninitialize();
  94. return ( SUCCEEDED( hRes ) );
  95. }
  96. // InstallURLSCanFix
  97. //
  98. // Install the fix for URLScan
  99. //
  100. DWORD InstallURLScanFix( LPTSTR szUrlScanPath )
  101. {
  102. BOOL bServiceWasRunning;
  103. DWORD dwRet = ERROR_SUCCESS;
  104. // Stop web Service
  105. if ( !StopWebSerivce( &bServiceWasRunning ) )
  106. {
  107. // Error Message about service not stopping
  108. return IDS_ERROR_WEBSERVICE;
  109. }
  110. // Update the Inf
  111. if ( !UpdateIni( szUrlScanPath ) )
  112. {
  113. dwRet = IDS_ERROR_INIUPDATE;
  114. }
  115. // Update Executable
  116. if ( ( dwRet == ERROR_SUCCESS ) &&
  117. ( !MoveOldUrlScan( szUrlScanPath ) ||
  118. !ExtractUrlScanFile( szUrlScanPath )
  119. )
  120. )
  121. {
  122. dwRet = IDS_ERROR_DLLUPDATE;
  123. }
  124. // Restart web service if it was running before,
  125. // even if there was a failure along the way
  126. if ( bServiceWasRunning &&
  127. !StartWebSerivce()
  128. )
  129. {
  130. // Error Message about not being able to start service
  131. if ( dwRet == ERROR_SUCCESS )
  132. {
  133. dwRet = IDS_ERROR_RESTARTWEB;
  134. }
  135. }
  136. return dwRet;
  137. }
  138. // ExtractUrlScanFile
  139. //
  140. // Extract the URLScan File to the FileSystem
  141. //
  142. // Parameters:
  143. // szPath - Path to expand to
  144. //
  145. // Return:
  146. // TRUE - Success
  147. // FALSE - Failure
  148. BOOL ExtractUrlScanFile( LPTSTR szPath )
  149. {
  150. HRSRC hrDllResource;
  151. HGLOBAL hDllResource;
  152. LPVOID pDllData;
  153. HANDLE hFile;
  154. DWORD dwBytesWritten;
  155. DWORD dwSize;
  156. BOOL bRet = FALSE;
  157. DWORD dwTryCount = 0;
  158. if ( ( ( hrDllResource = FindResource( NULL, (LPCWSTR) IDR_DATA1, RT_RCDATA) ) == NULL ) ||
  159. ( ( dwSize = SizeofResource( NULL, hrDllResource ) ) == 0 ) ||
  160. ( ( hDllResource = LoadResource( NULL, hrDllResource) ) == NULL ) ||
  161. ( ( pDllData = LockResource( hDllResource ) ) == NULL )
  162. )
  163. {
  164. // Could not load resource
  165. return FALSE;
  166. }
  167. do {
  168. hFile = CreateFile( szPath,
  169. GENERIC_WRITE,
  170. 0,
  171. NULL,
  172. CREATE_ALWAYS,
  173. FILE_ATTRIBUTE_NORMAL,
  174. NULL);
  175. if ( GetLastError() == ERROR_SHARING_VIOLATION )
  176. {
  177. // If we are getting a sharing violation, it is possible that inetinfo.exe
  178. // has released the handle, but the OS hasn't totally released it yet,
  179. // so lets wait 5 seconds
  180. Sleep( URLSCAN_DLL_INSTALL_INTERVAL );
  181. }
  182. dwTryCount++;
  183. } while ( ( hFile == INVALID_HANDLE_VALUE) &&
  184. ( GetLastError() == ERROR_SHARING_VIOLATION ) &&
  185. ( dwTryCount < URLSCAN_DLL_INSTALL_MAXTRIES ) );
  186. if ( hFile != INVALID_HANDLE_VALUE )
  187. {
  188. if ( WriteFile( hFile, pDllData, dwSize, &dwBytesWritten, NULL) )
  189. {
  190. bRet = TRUE;
  191. }
  192. CloseHandle(hFile);
  193. if ( dwBytesWritten != dwSize )
  194. {
  195. bRet = FALSE;
  196. }
  197. }
  198. return bRet;
  199. }
  200. // MoveOldUrlScan
  201. //
  202. // This will backup the old urlscan into a backup file location
  203. //
  204. // Parameters:
  205. // szCurrentPath - The current path to urlscan
  206. //
  207. BOOL MoveOldUrlScan( LPTSTR szCurrentPath )
  208. {
  209. TCHAR szBackupLocation[ MAX_PATH ];
  210. LPTSTR szCurrentPos;
  211. DWORD dwPathLength = (DWORD) _tcslen( szCurrentPath );
  212. if ( ( dwPathLength >= ( MAX_PATH - _tcslen(URLSCAN_DEFAULT_FILENAME) - _tcslen(URLSCAN_BACKUPKEY) - 1 ) ) ||
  213. ( dwPathLength == 0 )
  214. )
  215. {
  216. return FALSE;
  217. }
  218. // Copy Filelocation over
  219. _tcscpy( szBackupLocation, szCurrentPath );
  220. // Find Last '\'
  221. szCurrentPos = _tcsrchr( szBackupLocation, '\\' );
  222. // If there is not slash, then reset to begining of string
  223. if ( szCurrentPos == NULL )
  224. {
  225. szCurrentPos = szBackupLocation;
  226. }
  227. if ( *szCurrentPos == '\\' )
  228. {
  229. // Move forward one character to the first letter
  230. szCurrentPos++;
  231. }
  232. // Append New FileName
  233. _tcscpy( szCurrentPos, URLSCAN_BACKUPKEY);
  234. _tcscat( szCurrentPos, URLSCAN_DEFAULT_FILENAME);
  235. // Ignore Failure, since failure is most likely because we have done this
  236. // before, and the backup file already exists
  237. MoveFileEx( szCurrentPath, szBackupLocation, MOVEFILE_COPY_ALLOWED );
  238. return TRUE;
  239. }
  240. // IsAdministrator
  241. //
  242. // Return whether the user is an administrator or not
  243. //
  244. BOOL IsAdministrator()
  245. {
  246. SC_HANDLE hSCManager;
  247. BOOL bRet;
  248. hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE );
  249. bRet = hSCManager != NULL;
  250. if ( hSCManager )
  251. {
  252. CloseServiceHandle( hSCManager );
  253. }
  254. return bRet;
  255. }
  256. // UpdateRegistryforAddRemove
  257. //
  258. // Update the registry to reflect the new name for the uninstall
  259. // program
  260. //
  261. BOOL
  262. UpdateRegistryforAddRemove()
  263. {
  264. HKEY hRegKey;
  265. BOOL bRet;
  266. LPWSTR szValue = URLSCAN_TOOL_KEY_NEWVALUE;
  267. if ( RegOpenKey( HKEY_LOCAL_MACHINE,
  268. URLSCAN_TOOL_REGPATH,
  269. &hRegKey ) != ERROR_SUCCESS )
  270. {
  271. // Failure to open registry key
  272. // We will return success though, since they could of never installed
  273. // the installer, but only the file by itself manually.
  274. return TRUE;
  275. }
  276. bRet = RegSetValueEx( hRegKey,
  277. URLSCAN_TOOL_KEY_NAME, // Value Name
  278. NULL, // Reserved
  279. REG_SZ, // String Value
  280. (LPBYTE) szValue, // Value to set
  281. ( ( (DWORD) wcslen(szValue) + 1) * sizeof(WCHAR) )
  282. ) == ERROR_SUCCESS;
  283. RegCloseKey( hRegKey );
  284. return bRet;
  285. }