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.

531 lines
13 KiB

  1. #ifndef _WIN32_WINNT
  2. #define _WIN32_WINNT 0x0510
  3. #endif
  4. #include <windows.h>
  5. #include <tchar.h>
  6. #include <assert.h>
  7. #include <time.h>
  8. #include "common.h"
  9. #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
  10. #include <atlbase.h>
  11. //--------------------------------------------------------------------------
  12. void MyOutputDebug(TCHAR *fmt, ...)
  13. {
  14. #if defined( DBG ) || defined( _DEBUG )
  15. TCHAR szTime[ 10 ];
  16. TCHAR szDate[ 10 ];
  17. ::_tstrtime( szTime );
  18. ::_tstrdate( szDate );
  19. va_list marker;
  20. TCHAR szBuf[1024];
  21. size_t cbSize = ( sizeof( szBuf ) / sizeof( TCHAR ) ) - 1; // one byte for null
  22. _sntprintf( szBuf, cbSize, TEXT( "%s %s: " ), szDate, szTime );
  23. szBuf[ 1023 ] = '\0';
  24. cbSize -= _tcslen( szBuf );
  25. va_start( marker, fmt );
  26. _vsntprintf( szBuf + _tcslen( szBuf ), cbSize, fmt, marker );
  27. szBuf[ 1023 ] = '\0';
  28. cbSize -= _tcslen( szBuf );
  29. va_end( marker );
  30. _tcsncat(szBuf, TEXT("\r\n"), cbSize );
  31. OutputDebugString(szBuf);
  32. #endif
  33. }
  34. //--------------------------------------------------------------------------
  35. void Log( LPCTSTR fmt, ... )
  36. {
  37. TCHAR szTime[ 10 ];
  38. TCHAR szDate[ 10 ];
  39. ::_tstrtime( szTime );
  40. ::_tstrdate( szDate );
  41. va_list marker;
  42. TCHAR szBuf[1024];
  43. size_t cbSize = ( sizeof( szBuf ) / sizeof( TCHAR ) ) - 1; // one byte for null
  44. _sntprintf( szBuf, cbSize, TEXT( "%s %s: " ), szDate, szTime );
  45. szBuf[ 1023 ] = '\0';
  46. cbSize -= _tcslen( szBuf );
  47. va_start( marker, fmt );
  48. _vsntprintf( szBuf + _tcslen( szBuf ), cbSize, fmt, marker );
  49. szBuf[ 1023 ] = '\0';
  50. cbSize -= _tcslen( szBuf );
  51. va_end( marker );
  52. _tcsncat(szBuf, TEXT("\r\n"), cbSize );
  53. #if defined( DBG ) || defined( _DEBUG )
  54. OutputDebugString(szBuf);
  55. #endif
  56. // write the data out to the log file
  57. //char szBufA[ 1024 ];
  58. //WideCharToMultiByte( CP_ACP, 0, szBuf, -1, szBufA, 1024, NULL, NULL );
  59. TCHAR szLogFile[ MAX_PATH + 1 ];
  60. if( 0 == GetWindowsDirectory( szLogFile, MAX_PATH + 1 ) )
  61. return;
  62. _tcsncat( szLogFile, TEXT( "\\uddisetup.log" ), MAX_PATH - _tcslen( szLogFile ) );
  63. szLogFile[ MAX_PATH ] = NULL;
  64. HANDLE hFile = CreateFile(
  65. szLogFile, // file name
  66. GENERIC_WRITE, // open for writing
  67. 0, // do not share
  68. NULL, // no security
  69. OPEN_ALWAYS, // open and create if not exists
  70. FILE_ATTRIBUTE_NORMAL, // normal file
  71. NULL); // no attr. template
  72. if( hFile == INVALID_HANDLE_VALUE )
  73. {
  74. assert( false );
  75. return;
  76. }
  77. //
  78. // move the file pointer to the end so that we can append
  79. //
  80. SetFilePointer( hFile, 0, NULL, FILE_END );
  81. DWORD dwNumberOfBytesWritten;
  82. BOOL bOK = WriteFile(
  83. hFile,
  84. szBuf,
  85. (UINT) _tcslen( szBuf ) * sizeof( TCHAR ), // number of bytes to write
  86. &dwNumberOfBytesWritten, // number of bytes written
  87. NULL); // overlapped buffer
  88. assert( bOK );
  89. FlushFileBuffers ( hFile );
  90. CloseHandle( hFile );
  91. }
  92. //-----------------------------------------------------------------------------------------
  93. void ClearLog()
  94. {
  95. /*
  96. TCHAR szLogFile[ MAX_PATH ];
  97. if( 0 == GetWindowsDirectory( szLogFile, MAX_PATH ))
  98. {
  99. return;
  100. }
  101. _tcscat( szLogFile, TEXT( "\\" ) );
  102. _tcscat( szLogFile, UDDI_SETUP_LOG );
  103. ::DeleteFile( szLogFile );
  104. */
  105. Log( TEXT( "*******************************************************" ) );
  106. Log( TEXT( "********** Starting a new log *************************" ) );
  107. Log( TEXT( "*******************************************************" ) );
  108. //
  109. // now get the resource stamp
  110. //
  111. TCHAR szVerStamp[ 256 ];
  112. ZeroMemory( szVerStamp, sizeof szVerStamp );
  113. int iRet = GetFileVersionStr( szVerStamp, sizeof szVerStamp / sizeof szVerStamp[0] );
  114. if ( iRet )
  115. {
  116. Log( TEXT( "OCM DLL Version is not available" ) );
  117. }
  118. else
  119. {
  120. Log( TEXT( "OCM DLL Version is '%s'" ), szVerStamp );
  121. }
  122. }
  123. //-----------------------------------------------------------------------------------------
  124. void LogError( PTCHAR szAction, DWORD dwErrorCode )
  125. {
  126. LPVOID lpMsgBuf = NULL;
  127. FormatMessage(
  128. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  129. FORMAT_MESSAGE_FROM_SYSTEM |
  130. FORMAT_MESSAGE_IGNORE_INSERTS,
  131. NULL,
  132. dwErrorCode,
  133. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  134. (LPTSTR) &lpMsgBuf,
  135. 0,
  136. NULL
  137. );
  138. Log( TEXT( "----------------------------------------------------------" ) );
  139. Log( TEXT( "An error occurred during installation. Details follow:" ) );
  140. Log( TEXT( "Action: %s" ), szAction );
  141. Log( TEXT( "Message: %s" ), lpMsgBuf );
  142. Log( TEXT( "----------------------------------------------------------" ) );
  143. LocalFree( lpMsgBuf );
  144. }
  145. //--------------------------------------------------------------------------
  146. /*
  147. void Enter( PTCHAR szMsg )
  148. {
  149. #ifdef _DEBUG
  150. TCHAR szEnter[ 512 ];
  151. _stprintf( szEnter, TEXT( "Entering %s..." ), szMsg );
  152. Log( szEnter );
  153. #endif
  154. }
  155. */
  156. //--------------------------------------------------------------------------
  157. //
  158. // NOTE: The install path has a trailing backslash
  159. //
  160. bool GetUDDIInstallPath( PTCHAR szInstallPath, DWORD dwLen )
  161. {
  162. HKEY hKey;
  163. //
  164. // get the UDDI installation folder [TARGETDIR] from the registry. The installer squirrels it away there.
  165. //
  166. LONG iRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT( "SOFTWARE\\Microsoft\\UDDI" ), NULL, KEY_READ, &hKey );
  167. if( ERROR_SUCCESS != iRet )
  168. {
  169. LogError( TEXT( "Unable to open the UDDI registry key" ), iRet );
  170. return false;
  171. }
  172. DWORD dwType = REG_SZ;
  173. iRet = RegQueryValueEx( hKey, TEXT( "InstallRoot" ), 0, &dwType, (PBYTE) szInstallPath, &dwLen );
  174. if( ERROR_SUCCESS != iRet )
  175. {
  176. LogError( TEXT( "UDDI registry key did not have the InstallRoot value or buffer size was too small" ), iRet );
  177. }
  178. RegCloseKey( hKey );
  179. return ERROR_SUCCESS == iRet ? true : false;
  180. }
  181. //---------------------------------------------------------------------------------
  182. // Retrieves the calling module file version string
  183. //
  184. int GetFileVersionStr( LPTSTR outBuf, DWORD dwBufCharSize )
  185. {
  186. if ( IsBadStringPtr( outBuf, dwBufCharSize ) )
  187. return E_INVALIDARG;
  188. TCHAR fname[ MAX_PATH + 1 ];
  189. UINT cbSize;
  190. DWORD dwTmp;
  191. ZeroMemory (fname, sizeof fname);
  192. GetModuleFileName( NULL, fname, MAX_PATH );
  193. DWORD dwSize = GetFileVersionInfoSize( fname, &dwTmp );
  194. if (dwSize)
  195. {
  196. LANGANDCODEPAGE *lpCodePage = NULL;
  197. LPTSTR lpBlock = NULL;
  198. TCHAR subBlock[ 256 ];
  199. LPBYTE pVerBlock = new BYTE[dwSize + 1];
  200. if ( !pVerBlock )
  201. return E_OUTOFMEMORY;
  202. ZeroMemory (pVerBlock, dwSize + 1);
  203. BOOL bRes = GetFileVersionInfo( fname, dwTmp, dwSize, pVerBlock );
  204. if (!bRes) // there is no resource block
  205. {
  206. delete[] pVerBlock;
  207. return GetLastError();
  208. }
  209. bRes = VerQueryValue(pVerBlock, TEXT("\\VarFileInfo\\Translation"),
  210. (LPVOID*)&lpCodePage,
  211. &cbSize);
  212. if (!bRes)
  213. {
  214. delete[] pVerBlock;
  215. return GetLastError();
  216. }
  217. _stprintf( subBlock, TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
  218. lpCodePage->wLanguage,
  219. lpCodePage->wCodePage);
  220. // Retrieve file description for language and code page "i".
  221. bRes = VerQueryValue(pVerBlock, subBlock, (LPVOID *)&lpBlock, &cbSize);
  222. if (!bRes)
  223. {
  224. delete[] pVerBlock;
  225. return GetLastError();
  226. }
  227. _tcsncpy( outBuf, lpBlock, dwBufCharSize );
  228. delete[] pVerBlock;
  229. return 0;
  230. }
  231. return ERROR_RESOURCE_DATA_NOT_FOUND;
  232. }
  233. //---------------------------------------------------------------------------------------
  234. // Retrieves the SID and converts it to the string representation
  235. //
  236. BOOL GetLocalSidString( WELL_KNOWN_SID_TYPE sidType, LPTSTR szOutBuf, DWORD cbOutBuf )
  237. {
  238. BYTE tmpBuf[ 1024 ];
  239. LPTSTR szTmpStr = NULL;
  240. DWORD cbBuf = sizeof tmpBuf;
  241. BOOL bRes = CreateWellKnownSid( sidType, NULL, tmpBuf, &cbBuf );
  242. if( !bRes )
  243. return FALSE;
  244. bRes = ConvertSidToStringSid( tmpBuf, &szTmpStr );
  245. if( !bRes )
  246. return FALSE;
  247. _tcsncpy( szOutBuf, szTmpStr, cbOutBuf );
  248. LocalFree( szTmpStr );
  249. return TRUE;
  250. }
  251. BOOL GetLocalSidString( LPCTSTR szUserName, LPTSTR szOutBuf, DWORD cbOutBuf )
  252. {
  253. TCHAR szDomain[ 1024 ];
  254. LPTSTR szTmpStr = NULL;
  255. DWORD cbDomain = sizeof( szDomain ) / sizeof( szDomain[0] );
  256. SID_NAME_USE pUse;
  257. //
  258. // Try to allocate a buffer for the SID.
  259. //
  260. DWORD cbMaxSid = SECURITY_MAX_SID_SIZE;
  261. PSID psidUser = LocalAlloc( LMEM_FIXED, cbMaxSid );
  262. if( NULL == psidUser )
  263. {
  264. Log( _T( "Call to LocalAlloc failed." ) );
  265. return FALSE;
  266. }
  267. memset( psidUser, 0, cbMaxSid );
  268. BOOL bRes = LookupAccountName( NULL, szUserName, psidUser, &cbMaxSid, szDomain, &cbDomain, &pUse );
  269. if( !bRes )
  270. {
  271. LocalFree( psidUser );
  272. return FALSE;
  273. }
  274. bRes = ConvertSidToStringSid( psidUser, &szTmpStr );
  275. if( !bRes )
  276. {
  277. LocalFree( psidUser );
  278. return FALSE;
  279. }
  280. _tcsncpy( szOutBuf, szTmpStr, cbOutBuf );
  281. LocalFree( szTmpStr );
  282. LocalFree( psidUser );
  283. return TRUE;
  284. }
  285. BOOL GetRemoteAcctName( LPCTSTR szMachineName, LPCTSTR szSidStr, LPTSTR szOutStr, LPDWORD cbOutStr, LPTSTR szDomain, LPDWORD cbDomain )
  286. {
  287. PSID pSid = NULL;
  288. SID_NAME_USE puse;
  289. BOOL bRes = ConvertStringSidToSid( szSidStr, &pSid );
  290. if( !bRes )
  291. return FALSE;
  292. bRes = LookupAccountSid( szMachineName, pSid, szOutStr, cbOutStr, szDomain, cbDomain, &puse );
  293. LocalFree( pSid );
  294. return bRes;
  295. }
  296. HRESULT GetOSProductSuiteMask( LPCTSTR szRemoteServer, UINT *pdwMask )
  297. {
  298. HRESULT hr = S_OK;
  299. BSTR bstrWQL = NULL;
  300. if ( IsBadWritePtr( pdwMask, sizeof UINT ) )
  301. return E_INVALIDARG;
  302. hr = CoInitializeEx( 0, COINIT_SPEED_OVER_MEMORY | COINIT_MULTITHREADED );
  303. if ( FAILED( hr ) )
  304. return hr;
  305. try
  306. {
  307. DWORD retCount = 0;
  308. TCHAR buf[ 512 ] = {0};
  309. LPCTSTR locatorPath = L"//%s/root/cimv2";
  310. CComBSTR objQry = L"SELECT * FROM Win32_OperatingSystem";
  311. CComPtr<IWbemClassObject> pWMIOS;
  312. CComPtr<IWbemServices> pWMISvc;
  313. CComPtr<IWbemLocator> pWMILocator;
  314. CComPtr<IEnumWbemClassObject> pWMIEnum;
  315. //
  316. // First, compose the locator string
  317. //
  318. if ( szRemoteServer )
  319. {
  320. _stprintf( buf, locatorPath, szRemoteServer );
  321. }
  322. else
  323. {
  324. _stprintf( buf, locatorPath, _T(".") );
  325. }
  326. BSTR bstrBuf = ::SysAllocString( buf );
  327. if( NULL == bstrBuf )
  328. {
  329. throw hr;
  330. }
  331. //
  332. // now create the locator and set up the security blanket
  333. //
  334. hr = CoInitializeSecurity( NULL, -1, NULL, NULL,
  335. RPC_C_AUTHN_LEVEL_DEFAULT,
  336. RPC_C_IMP_LEVEL_IMPERSONATE,
  337. NULL, EOAC_NONE, NULL);
  338. if ( FAILED( hr ) && hr != RPC_E_TOO_LATE )
  339. {
  340. ::SysFreeString( bstrBuf );
  341. throw hr;
  342. }
  343. hr = pWMILocator.CoCreateInstance( CLSID_WbemLocator );
  344. if( FAILED(hr) )
  345. {
  346. ::SysFreeString( bstrBuf );
  347. throw hr;
  348. }
  349. hr = pWMILocator->ConnectServer( bstrBuf, NULL, NULL, NULL,
  350. WBEM_FLAG_CONNECT_USE_MAX_WAIT,
  351. NULL, NULL, &pWMISvc );
  352. ::SysFreeString( bstrBuf );
  353. if( FAILED(hr) )
  354. {
  355. throw hr;
  356. }
  357. hr = CoSetProxyBlanket( pWMISvc,
  358. RPC_C_AUTHN_WINNT,
  359. RPC_C_AUTHZ_NONE,
  360. NULL,
  361. RPC_C_AUTHN_LEVEL_CALL,
  362. RPC_C_IMP_LEVEL_IMPERSONATE,
  363. NULL,
  364. EOAC_NONE );
  365. if( FAILED(hr) )
  366. {
  367. throw hr;
  368. }
  369. //
  370. // Now get the Win32_OperatingSystem instances and check the first one found
  371. //
  372. bstrWQL = ::SysAllocString( L"WQL" );
  373. if( NULL == bstrWQL )
  374. {
  375. throw hr;
  376. }
  377. hr = pWMISvc->ExecQuery( bstrWQL, objQry,
  378. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_ENSURE_LOCATABLE,
  379. NULL, &pWMIEnum );
  380. if (FAILED(hr))
  381. throw hr;
  382. hr = pWMIEnum->Next( 60000, 1, &pWMIOS, &retCount );
  383. if ( hr == WBEM_S_NO_ERROR )
  384. {
  385. VARIANT vt;
  386. CIMTYPE cimType;
  387. long flavor = 0;
  388. ZeroMemory( &vt, sizeof vt );
  389. VariantInit ( &vt );
  390. hr = pWMIOS->Get( L"SuiteMask", 0, &vt, &cimType, &flavor );
  391. if ( FAILED( hr ) )
  392. throw hr;
  393. if ( vt.vt == VT_NULL || vt.vt == VT_EMPTY )
  394. throw E_FAIL;
  395. hr = VariantChangeType( &vt, &vt, 0, VT_UINT );
  396. if ( FAILED( hr ) )
  397. throw hr;
  398. *pdwMask = vt.uintVal;
  399. VariantClear( &vt );
  400. }
  401. }
  402. catch ( HRESULT hrErr )
  403. {
  404. hr = hrErr;
  405. ::SysFreeString( bstrWQL ); // it's OK to call SysFreeString with NULL.
  406. }
  407. catch (...)
  408. {
  409. hr = E_UNEXPECTED;
  410. }
  411. CoUninitialize();
  412. return hr;
  413. }
  414. HRESULT IsStandardServer( LPCTSTR szRemoteServer, BOOL *bResult )
  415. {
  416. if ( IsBadWritePtr( bResult, sizeof BOOL ) )
  417. return E_INVALIDARG;
  418. UINT uMask = 0;
  419. HRESULT hr = GetOSProductSuiteMask( szRemoteServer, &uMask );
  420. if ( FAILED( hr ) )
  421. return hr;
  422. if ( ( uMask & VER_SUITE_DATACENTER ) || ( uMask & VER_SUITE_ENTERPRISE ) )
  423. *bResult = FALSE;
  424. else
  425. *bResult = TRUE;
  426. return S_OK;
  427. }