Source code of Windows XP (NT5)
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.

1040 lines
28 KiB

  1. #include "pchealth.h"
  2. #include <FWcommon.h>
  3. #include <strings.h>
  4. #include <DllUtils.h>
  5. #include <BrodCast.h>
  6. #include <lmerr.h>
  7. #include <confgmgr.h>
  8. #include <createmutexasprocess.h>
  9. // sets a status object with one single missing privilege
  10. void SetSinglePrivilegeStatusObject(MethodContext* pContext, const WCHAR* pPrivilege)
  11. {
  12. SAFEARRAY *psaPrivilegesReqd, *psaPrivilegesNotHeld;
  13. SAFEARRAYBOUND rgsabound[1];
  14. rgsabound[0].cElements = 1;
  15. rgsabound[0].lLbound = 0;
  16. psaPrivilegesReqd = SafeArrayCreate(VT_BSTR, 1, rgsabound);
  17. psaPrivilegesNotHeld = SafeArrayCreate(VT_BSTR, 1, rgsabound);
  18. if (psaPrivilegesReqd && psaPrivilegesNotHeld)
  19. {
  20. long index = 0;
  21. bstr_t privilege(pPrivilege);
  22. SafeArrayPutElement(psaPrivilegesReqd, &index, (void*)(BSTR)privilege);
  23. SafeArrayPutElement(psaPrivilegesNotHeld, &index, (void*)(BSTR)privilege);
  24. CWbemProviderGlue::SetStatusObject(pContext, IDS_CimWin32Namespace, "Required privilege not enabled", WBEM_E_FAILED, psaPrivilegesNotHeld, psaPrivilegesReqd);
  25. }
  26. if (psaPrivilegesNotHeld)
  27. SafeArrayDestroy(psaPrivilegesNotHeld);
  28. if (psaPrivilegesReqd)
  29. SafeArrayDestroy(psaPrivilegesReqd);
  30. }
  31. // VER_PLATFORM_WIN32s Win32s on Windows 3.1
  32. // VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95
  33. // VER_PLATFORM_WIN32_NT Windows NT
  34. DWORD GetPlatformID(void)
  35. {
  36. OSVERSIONINFO OsVersion;
  37. OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  38. GetVersionEx((LPOSVERSIONINFO)&OsVersion);
  39. return OsVersion.dwPlatformId;
  40. }
  41. // 3 for NT 3.51
  42. // 4 for NT 4.0, W95 & W98
  43. DWORD GetPlatformMajorVersion(void)
  44. {
  45. OSVERSIONINFO OsVersion;
  46. OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  47. GetVersionEx((LPOSVERSIONINFO)&OsVersion);
  48. return OsVersion.dwMajorVersion;
  49. }
  50. // 0 for W95, 10 for 98
  51. DWORD GetPlatformMinorVersion(void)
  52. {
  53. OSVERSIONINFO OsVersion;
  54. OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  55. GetVersionEx((LPOSVERSIONINFO)&OsVersion);
  56. return OsVersion.dwMinorVersion;
  57. }
  58. // returns TRUE iff the current OS is Win 98+
  59. // false for NT or Win 95
  60. bool IsWin98(void)
  61. {
  62. OSVERSIONINFO OsVersion;
  63. OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  64. GetVersionEx((LPOSVERSIONINFO)&OsVersion);
  65. return (OsVersion.dwPlatformId == (VER_PLATFORM_WIN32_WINDOWS) && (OsVersion.dwMinorVersion >= 10));
  66. }
  67. bool IsWinNT5(void)
  68. {
  69. OSVERSIONINFO OsVersion;
  70. OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  71. GetVersionEx((LPOSVERSIONINFO)&OsVersion);
  72. return(OsVersion.dwPlatformId == (VER_PLATFORM_WIN32_NT) && (OsVersion.dwMajorVersion >= 5));
  73. }
  74. bool IsWinNT4(void)
  75. {
  76. OSVERSIONINFO OsVersion;
  77. OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  78. GetVersionEx((LPOSVERSIONINFO)&OsVersion);
  79. return(OsVersion.dwPlatformId == (VER_PLATFORM_WIN32_NT) && (OsVersion.dwMajorVersion == 4));
  80. }
  81. bool IsWinNT351(void)
  82. {
  83. OSVERSIONINFO OsVersion;
  84. OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  85. GetVersionEx((LPOSVERSIONINFO)&OsVersion);
  86. return ( OsVersion.dwPlatformId == VER_PLATFORM_WIN32_NT
  87. && OsVersion.dwMajorVersion == 3
  88. && OsVersion.dwMinorVersion == 51 );
  89. }
  90. /////////////////////////////////////////////////////////////////////
  91. void LogEnumValueError( char * szFile, DWORD dwLine, char * szKey, char * szId )
  92. {
  93. if (IsErrorLoggingEnabled())
  94. {
  95. CHString gazotta;
  96. gazotta.Format(ERR_REGISTRY_ENUM_VALUE_FOR_KEY, szId, szKey);
  97. LogErrorMessageEx((const char *)gazotta, szFile, dwLine);
  98. }
  99. }
  100. /////////////////////////////////////////////////////////////////////
  101. void LogOpenRegistryError( char * szFile, DWORD dwLine, char * szKey )
  102. {
  103. if (IsErrorLoggingEnabled())
  104. {
  105. CHString gazotta;
  106. gazotta.Format(ERR_OPEN_REGISTRY, szKey);
  107. LogErrorMessageEx((const char *)gazotta, szFile, dwLine);
  108. }
  109. }
  110. /////////////////////////////////////////////////////////////////////
  111. // left in for hysterical purposes
  112. // prefer to use LogMessage macro in BrodCast.h
  113. void LogError( char * szFile, DWORD dwLine, char * szKey )
  114. {
  115. LogErrorMessageEx(szKey, szFile, dwLine);
  116. }
  117. /////////////////////////////////////////////////////////////////////
  118. void LogLastError( char * szFile, DWORD dwLine )
  119. {
  120. if (IsErrorLoggingEnabled())
  121. {
  122. DWORD duhWord = GetLastError();
  123. CHString gazotta;
  124. gazotta.Format(IDS_GETLASTERROR, duhWord, duhWord);
  125. LogErrorMessageEx(gazotta, szFile, dwLine);
  126. }
  127. }
  128. ///////////////////////////////////////////////////////////////////////
  129. BOOL GetValue( CRegistry & Reg,
  130. char * szKey,
  131. char * ValueName,
  132. CHString * pchsValueBuffer )
  133. {
  134. BOOL bRet = (Reg.GetCurrentKeyValue( ValueName, *pchsValueBuffer) == ERROR_SUCCESS);
  135. if( !bRet )
  136. LogEnumValueError(__FILE__,__LINE__, szKey, ValueName);
  137. return bRet;
  138. }
  139. ///////////////////////////////////////////////////////////////////////
  140. BOOL GetValue( CRegistry & Reg,
  141. char * szKey,
  142. char * ValueName,
  143. DWORD * dwValueBuffer )
  144. {
  145. BOOL bRet = (Reg.GetCurrentKeyValue( ValueName, *dwValueBuffer) == ERROR_SUCCESS);
  146. if( !bRet )
  147. LogEnumValueError(__FILE__,__LINE__, szKey, ValueName);
  148. return bRet;
  149. }
  150. ///////////////////////////////////////////////////////////////////////
  151. BOOL OpenAndGetValue( CRegistry & Reg,
  152. char * szKey,
  153. char * ValueName,
  154. CHString * pchsValueBuffer )
  155. {
  156. BOOL bRet = ( Reg.OpenLocalMachineKeyAndReadValue( szKey, ValueName, *pchsValueBuffer )== ERROR_SUCCESS);
  157. if( !bRet )
  158. LogEnumValueError(__FILE__,__LINE__, szKey, ValueName);
  159. return bRet;
  160. }
  161. ///////////////////////////////////////////////////////////////////////
  162. BOOL GetBinaryValue( CRegistry & Reg, char * szKey,
  163. char * ValueName, CHString * pchsValueBuffer )
  164. {
  165. BOOL bRet = ( Reg.GetCurrentBinaryKeyValue( ValueName, *pchsValueBuffer) == ERROR_SUCCESS);
  166. if( !bRet )
  167. (LogEnumValueError(__FILE__,__LINE__, szKey, ValueName));
  168. return bRet;
  169. }
  170. /*****************************************************************************
  171. *
  172. * FUNCTION : GetDeviceParms
  173. *
  174. * DESCRIPTION : Gets drive characteristics (heads, tracks, cylinders, etc)
  175. *
  176. * INPUTS : Pointer to a DEVICEPARMS struct to receive the data
  177. * Drive number of the drive to query (0 = default drive,
  178. * 1 = A, 2 = B, and so on)
  179. *
  180. * OUTPUTS :
  181. *
  182. * RETURNS : TRUE if successful, FALSE otherwise
  183. *
  184. * COMMENTS :
  185. *
  186. *****************************************************************************/
  187. BOOL GetDeviceParms(PDEVICEPARMS pstDeviceParms, UINT nDrive)
  188. {
  189. DEVIOCTL_REGISTERS reg;
  190. memset(&reg, '\0', sizeof(DEVIOCTL_REGISTERS));
  191. reg.reg_EAX = 0x440D; /* IOCTL for block devices */
  192. reg.reg_EBX = nDrive; /* zero-based drive ID */
  193. reg.reg_ECX = 0x0860; /* Get Media ID command */
  194. reg.reg_EDX = (DWORD) pstDeviceParms;
  195. memset(pstDeviceParms, 0, sizeof(DEVICEPARMS));
  196. if (!VWIN32IOCTL(&reg, VWIN32_DIOC_DOS_IOCTL))
  197. return FALSE;
  198. if (reg.reg_Flags & 0x8000) /* error if carry flag set */
  199. return FALSE;
  200. return TRUE;
  201. }
  202. /*****************************************************************************
  203. *
  204. * FUNCTION : GetDriveMapInfo
  205. *
  206. * DESCRIPTION : Gets logical to physical mapping info
  207. *
  208. * INPUTS : Pointer to a DRIVE_MAP_INFO struct to receive the data
  209. * Drive number of the drive to query (0 = default drive,
  210. * 1 = A, 2 = B, and so on)
  211. *
  212. * OUTPUTS :
  213. *
  214. * RETURNS : TRUE if successful, FALSE otherwise
  215. *
  216. * COMMENTS :
  217. *
  218. *****************************************************************************/
  219. BOOL GetDriveMapInfo(PDRIVE_MAP_INFO pDriveMapInfo, UINT nDrive)
  220. {
  221. DEVIOCTL_REGISTERS reg;
  222. memset(&reg, '\0', sizeof(DEVIOCTL_REGISTERS));
  223. reg.reg_EAX = 0x440d; /* IOCTL for block devices */
  224. reg.reg_EBX = nDrive; /* zero-based drive ID */
  225. reg.reg_ECX = 0x086f; /* Get Drive Map Info */
  226. reg.reg_EDX = (DWORD) pDriveMapInfo;
  227. // zero the struct
  228. memset(pDriveMapInfo, 0, sizeof(DRIVE_MAP_INFO));
  229. // Set the length byte
  230. pDriveMapInfo->btAllocationLength = sizeof(DRIVE_MAP_INFO);
  231. // Doit
  232. if (!VWIN32IOCTL(&reg, VWIN32_DIOC_DOS_IOCTL))
  233. return FALSE;
  234. if (reg.reg_Flags & 0x8000) {/* error if carry flag set */
  235. return FALSE;
  236. }
  237. return TRUE;
  238. }
  239. /*****************************************************************************
  240. *
  241. * FUNCTION : Get_ExtFreeSpace
  242. *
  243. * DESCRIPTION : Gets detailed info about a partition
  244. *
  245. * INPUTS : Drive number of the drive to query (0 = default drive,
  246. * 1 = A, 2 = B, and so on)
  247. * Pointer to ExtGetDskFreSpcStruct
  248. *
  249. * OUTPUTS :
  250. *
  251. * RETURNS : TRUE if successful, FALSE otherwise
  252. *
  253. * COMMENTS :
  254. *
  255. *****************************************************************************/
  256. BOOL Get_ExtFreeSpace(BYTE btDriveName, ExtGetDskFreSpcStruc *pstExtGetDskFreSpcStruc)
  257. {
  258. DEVIOCTL_REGISTERS reg;
  259. memset(&reg, '\0', sizeof(DEVIOCTL_REGISTERS));
  260. char szDrive[4];
  261. szDrive[0] = btDriveName;
  262. szDrive[1] = ':';
  263. szDrive[2] = '\\';
  264. szDrive[3] = '\0';
  265. reg.reg_EAX = 0x7303; // Get_ExtFreeSpace
  266. reg.reg_ECX = sizeof(ExtGetDskFreSpcStruc); // Size of the structure sent in
  267. reg.reg_EDI = (DWORD)pstExtGetDskFreSpcStruc; // Structure
  268. reg.reg_EDX = (DWORD)szDrive; // Drive to get info for
  269. // zero the struct
  270. memset(pstExtGetDskFreSpcStruc, 0, sizeof(ExtGetDskFreSpcStruc));
  271. // Doit
  272. if (!VWIN32IOCTL(&reg, VWIN32_DIOC_DOS_DRIVEINFO))
  273. return FALSE;
  274. if (reg.reg_Flags & 0x8000) {/* error if carry flag set */
  275. return FALSE;
  276. }
  277. return TRUE;
  278. }
  279. /*****************************************************************************
  280. *
  281. * FUNCTION : VWIN32IOCTL
  282. *
  283. * DESCRIPTION : Calls IOControl against the vwin32 vxd
  284. *
  285. * INPUTS : Pointer to DEVIOCTL_REGISTERS structure
  286. * IOControl call number.
  287. *
  288. * OUTPUTS :
  289. *
  290. * RETURNS : TRUE if successful, FALSE otherwise
  291. *
  292. * COMMENTS :
  293. *
  294. *****************************************************************************/
  295. BOOL VWIN32IOCTL(PDEVIOCTL_REGISTERS preg, DWORD dwCall)
  296. {
  297. HANDLE hDevice;
  298. BOOL fResult;
  299. DWORD cb;
  300. preg->reg_Flags = 0x8000; /* assume error (carry flag set) */
  301. hDevice = CreateFile("\\\\.\\VWIN32", 0, 0, 0, OPEN_EXISTING,
  302. FILE_FLAG_DELETE_ON_CLOSE, 0);
  303. if (hDevice == (HANDLE) INVALID_HANDLE_VALUE) {
  304. return FALSE;
  305. } else {
  306. fResult = DeviceIoControl(hDevice, dwCall, preg, sizeof(*preg), preg, sizeof(*preg), &cb, 0);
  307. }
  308. CloseHandle(hDevice);
  309. if (!fResult) {
  310. return FALSE;
  311. }
  312. return TRUE;
  313. }
  314. CHString GetFileTypeDescription(char *szExtension)
  315. {
  316. CRegistry RegInfo;
  317. CHString sTemp, sType(szExtension);
  318. if (RegInfo.Open(HKEY_CLASSES_ROOT, szExtension, KEY_READ) == ERROR_SUCCESS) {
  319. RegInfo.GetCurrentKeyValue("", sTemp);
  320. if (RegInfo.Open(HKEY_CLASSES_ROOT, sTemp, KEY_READ) == ERROR_SUCCESS) {
  321. RegInfo.GetCurrentKeyValue("", sType);
  322. }
  323. }
  324. return sType;
  325. }
  326. ///////////////////////////////////////////////////////////////////
  327. //
  328. // Define the severity codes
  329. //
  330. // Sev - is the severity code
  331. //
  332. // 00 - Success
  333. // 01 - Informational
  334. // 10 - Warning
  335. // 11 - Error
  336. //
  337. // Define the severity codes
  338. //
  339. //
  340. // Define the severity codes
  341. //
  342. #define STATUS_SEVERITY_WARNING 0x2
  343. #define STATUS_SEVERITY_SUCCESS 0x0
  344. #define STATUS_SEVERITY_INFORMATIONAL 0x1
  345. #define STATUS_SEVERITY_ERROR 0x3
  346. #define SEV_MASK 0xC0000000
  347. void TranslateNTStatus( DWORD dwStatus, CHString & chsValue)
  348. {
  349. switch((dwStatus & SEV_MASK) >> 30){
  350. case STATUS_SEVERITY_WARNING:
  351. chsValue = IDS_STATUS_Degraded;
  352. break;
  353. case STATUS_SEVERITY_SUCCESS:
  354. chsValue = IDS_STATUS_OK;
  355. break;
  356. case STATUS_SEVERITY_ERROR:
  357. chsValue = IDS_STATUS_Error;
  358. break;
  359. case STATUS_SEVERITY_INFORMATIONAL:
  360. chsValue = IDS_STATUS_OK;
  361. break;
  362. default:
  363. chsValue = IDS_STATUS_Unknown;
  364. }
  365. }
  366. BOOL GetVarFromVersionInfo(LPCTSTR szFile, LPCTSTR szVar, CHString &strValue)
  367. {
  368. BOOL fRc = FALSE;
  369. DWORD dwTemp,
  370. dwBlockSize;
  371. LPVOID pInfo = NULL;
  372. try
  373. {
  374. dwBlockSize = GetFileVersionInfoSize((LPTSTR) szFile, &dwTemp);
  375. if (dwBlockSize)
  376. {
  377. pInfo = (LPVOID) new BYTE[dwBlockSize + 4];
  378. memset( pInfo, NULL, dwBlockSize + 4);
  379. if (pInfo)
  380. {
  381. UINT len;
  382. if (GetFileVersionInfo((LPTSTR) szFile, 0, dwBlockSize, pInfo))
  383. {
  384. WORD wLang = 0;
  385. WORD wCodePage = 0;
  386. if(!GetVersionLanguage(pInfo, &wLang, &wCodePage) )
  387. {
  388. // on failure: default to English
  389. // this returns a pointer to an array of WORDs
  390. WORD *pArray;
  391. if (VerQueryValue(pInfo, "\\VarFileInfo\\Translation",(void **)(&pArray), &len))
  392. {
  393. len = len / sizeof(WORD);
  394. // find the english one...
  395. for (int i = 0; i < len; i += 2)
  396. {
  397. if( pArray[i] == 0x0409 ) {
  398. wLang = pArray[i];
  399. wCodePage = pArray[i + 1];
  400. break;
  401. }
  402. }
  403. }
  404. }
  405. TCHAR *pMfg, szTemp[256];
  406. wsprintf(szTemp, _T("\\StringFileInfo\\%04X%04X\\%s"), wLang, wCodePage, szVar);
  407. if( VerQueryValue(pInfo, szTemp, (void **)(&pMfg), &len))
  408. {
  409. strValue = pMfg;
  410. fRc = TRUE;
  411. }
  412. }
  413. }
  414. }
  415. }
  416. catch(...)
  417. {
  418. // We don't need to do anything, just need to protect ourselves
  419. // from the flaky version.dll calls.
  420. }
  421. if (pInfo)
  422. delete pInfo;
  423. return fRc;
  424. }
  425. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  426. Function: BOOL GetVersionLanguage(void *vpInfo,
  427. WORD *wpLang,
  428. WORD *wpCodePage);
  429. Description: This function extracts the language and codepage out of a passed GetFileVersionInfo()
  430. result. Consideration is given to variation in the layout.
  431. Arguments: vpInfo, wpLang, wpCodePage
  432. Returns: Boolean
  433. Inputs:
  434. Outputs:
  435. Caveats:
  436. Courtesy of: SMS, Nick Dyer
  437. Raid:
  438. History: a-peterc 30-Oct-1998 Created
  439. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  440. BOOL GetVersionLanguage(void *vpInfo, WORD *wpLang, WORD *wpCodePage)
  441. {
  442. WORD *wpTemp;
  443. WORD wLength;
  444. WCHAR *wcpTemp;
  445. char *cpTemp;
  446. BOOL bRet = FALSE;
  447. wpTemp = (WORD *) vpInfo;
  448. cpTemp = (char *) vpInfo;
  449. wpTemp++; // jump past buffer length.
  450. wLength = *wpTemp; // capture value length.
  451. wpTemp++; // skip past value length to what should be type code in new format
  452. if (*wpTemp == 0 || *wpTemp == 1) // new format expect unicode strings.
  453. {
  454. cpTemp = cpTemp + 38 + wLength + 8;
  455. wcpTemp = (WCHAR *) cpTemp;
  456. if (wcscmp(L"StringFileInfo", wcpTemp) == 0) // OK! were aligned properly.
  457. {
  458. bRet = TRUE;
  459. cpTemp += 30; // skip over "StringFileInfo"
  460. while ((DWORD) cpTemp % 4 > 0) // 32 bit align
  461. cpTemp++;
  462. cpTemp += 6; // skip over length and type fields.
  463. wcpTemp = (WCHAR *) cpTemp;
  464. swscanf(wcpTemp, L"%4x%4x", wpLang, wpCodePage);
  465. }
  466. }
  467. else // old format, expect single byte character strings.
  468. {
  469. cpTemp += 20 + wLength + 4;
  470. if (strcmp("StringFileInfo", cpTemp) == 0) // OK! were aligned properly.
  471. {
  472. bRet = TRUE;
  473. cpTemp += 20; // skip over length fields.
  474. sscanf(cpTemp, "%4x%4x", wpLang, wpCodePage);
  475. }
  476. }
  477. return (bRet);
  478. }
  479. ///////////////////////////////////////////////////////////////////
  480. BOOL GetManufacturerFromFileName(LPCTSTR szFile, CHString &strMfg)
  481. {
  482. return GetVarFromVersionInfo(szFile, "CompanyName", strMfg);
  483. }
  484. BOOL GetVersionFromFileName(LPCTSTR szFile, CHString &strVersion)
  485. {
  486. return GetVarFromVersionInfo(szFile, "ProductVersion", strVersion);
  487. }
  488. void ReplaceString(CHString &str, LPCTSTR szFind, LPCTSTR szReplace)
  489. {
  490. int iWhere,
  491. nLen = lstrlen(szFind);
  492. while ((iWhere = str.Find(szFind)) != -1)
  493. {
  494. str.Format(
  495. "%s%s%s",
  496. (LPCTSTR) str.Left(iWhere),
  497. szReplace,
  498. (LPCTSTR) str.Mid(iWhere + nLen));
  499. }
  500. }
  501. BOOL GetServiceFileName(LPCTSTR szService, CHString &strFileName)
  502. {
  503. SC_HANDLE hSCManager,
  504. hService;
  505. TCHAR szBuffer[2048];
  506. QUERY_SERVICE_CONFIG
  507. *pConfig = (QUERY_SERVICE_CONFIG *) szBuffer;
  508. DWORD dwNeeded;
  509. BOOL bRet = FALSE;
  510. hSCManager =
  511. OpenSCManager(
  512. NULL,
  513. NULL,
  514. STANDARD_RIGHTS_REQUIRED);
  515. if (!hSCManager)
  516. return FALSE;
  517. hService =
  518. OpenService(
  519. hSCManager,
  520. szService,
  521. SERVICE_QUERY_CONFIG);
  522. if (hService)
  523. {
  524. if (QueryServiceConfig(
  525. hService,
  526. pConfig,
  527. sizeof(szBuffer),
  528. &dwNeeded))
  529. {
  530. strFileName = pConfig->lpBinaryPathName;
  531. // Now fix up the path so that it has a drive letter.
  532. strFileName.MakeUpper();
  533. // If the filename is using \SYSTEMROOT\, replace it with %SystemRoot%.
  534. if (strFileName.Find("\\SYSTEMROOT\\") == 0)
  535. ReplaceString(strFileName, "\\SYSTEMROOT\\", "%SystemRoot%\\");
  536. // If the filename doesn't start with a replacement string, and if it
  537. // doesn't have a drive letter, assume it should start with
  538. // %SystemRoot%.
  539. else if (strFileName.GetLength() >= 2 &&
  540. strFileName[0] != '%' && strFileName[1] != ':')
  541. {
  542. CHString strTemp;
  543. strTemp.Format("%%SystemRoot%%\\%s", (LPCTSTR) strFileName);
  544. strFileName = strTemp;
  545. }
  546. TCHAR szOut[MAX_PATH * 2];
  547. ExpandEnvironmentStrings(strFileName, szOut, sizeof(szOut));
  548. strFileName = szOut;
  549. bRet = TRUE;
  550. }
  551. CloseServiceHandle(hService);
  552. }
  553. CloseServiceHandle(hSCManager);
  554. return bRet;
  555. }
  556. ///////////////////////////////////////////////////////////////////
  557. // Performs a case insensitive compare (such as is required for keys)
  558. // on two variants and returns true if they are the same type and
  559. // the same value, else false. Note that arrays, VT_NULL, and
  560. // embedded objects will assert, and return false.
  561. ///////////////////////////////////////////////////////////////////
  562. bool CompareVariantsNoCase(const VARIANT *v1, const VARIANT *v2)
  563. {
  564. if (v1->vt == v2->vt) {
  565. switch (v1->vt) {
  566. case VT_BOOL: return (v1->boolVal == v2->boolVal);
  567. case VT_UI1: return (v1->bVal == v2->bVal);
  568. case VT_I2: return (v1->iVal == v2->iVal);
  569. case VT_I4: return (v1->lVal == v2->lVal);
  570. case VT_R4: return (v1->fltVal == v2->fltVal);
  571. case VT_R8: return (v1->dblVal == v2->dblVal);
  572. case VT_BSTR: return (0 == _wcsicmp(v1->bstrVal, v2->bstrVal));
  573. default:
  574. ASSERT_BREAK(0);
  575. }
  576. }
  577. return false;
  578. }
  579. // map standard API return values (defined WinError.h)
  580. // to WBEMish hresults (defined in WbemCli.h)
  581. HRESULT WinErrorToWBEMhResult(LONG error)
  582. {
  583. HRESULT hr = WBEM_E_FAILED;
  584. switch (error)
  585. {
  586. case ERROR_SUCCESS:
  587. hr = WBEM_S_NO_ERROR;
  588. break;
  589. case ERROR_ACCESS_DENIED:
  590. hr = WBEM_E_ACCESS_DENIED;
  591. break;
  592. case ERROR_NOT_ENOUGH_MEMORY:
  593. case ERROR_OUTOFMEMORY:
  594. hr = WBEM_E_OUT_OF_MEMORY;
  595. break;
  596. case ERROR_ALREADY_EXISTS:
  597. hr = WBEM_E_ALREADY_EXISTS;
  598. break;
  599. case ERROR_BAD_NETPATH:
  600. case ERROR_INVALID_DATA:
  601. case ERROR_BAD_PATHNAME:
  602. case REGDB_E_INVALIDVALUE:
  603. case ERROR_PATH_NOT_FOUND:
  604. case ERROR_FILE_NOT_FOUND:
  605. case ERROR_BAD_USERNAME:
  606. case NERR_NetNameNotFound:
  607. case ERROR_NOT_READY:
  608. case ERROR_INVALID_NAME:
  609. hr = WBEM_E_NOT_FOUND;
  610. break;
  611. default:
  612. hr = WBEM_E_FAILED;
  613. }
  614. return hr;
  615. }
  616. void SetConfigMgrProperties(CConfigMgrDevice *pDevice, CInstance *pInstance)
  617. {
  618. CHString strDeviceID;
  619. DWORD dwStatus,
  620. dwProblem;
  621. if (pDevice->GetDeviceID(strDeviceID))
  622. pInstance->SetCHString(IDS_PNPDeviceID, strDeviceID);
  623. if (pDevice->GetStatus(&dwStatus, &dwProblem))
  624. pInstance->SetDWORD("ConfigManagerErrorCode", dwProblem);
  625. pInstance->SetDWORD("ConfigManagerUserConfig",
  626. pDevice->IsUsingForcedConfig());
  627. }
  628. BOOL EnablePrivilegeOnCurrentThread(LPCTSTR szPriv)
  629. {
  630. BOOL bRet = FALSE;
  631. HANDLE hToken = NULL;
  632. TOKEN_PRIVILEGES tkp;
  633. BOOL bLookup = FALSE;
  634. DWORD dwLastError = ERROR_SUCCESS;
  635. // Try to open the thread token. If we fail, it's because no
  636. // impersonation is going on, so call ImpersonateSelf to get a token.
  637. // Then call OpenThreadToken again.
  638. if (OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES |
  639. TOKEN_QUERY, FALSE, &hToken) ||
  640. (ImpersonateSelf(SecurityImpersonation) &&
  641. OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES |
  642. TOKEN_QUERY, FALSE, &hToken)))
  643. {
  644. {
  645. CreateMutexAsProcess createMutexAsProcess(SECURITYAPIMUTEXNAME);
  646. bLookup = LookupPrivilegeValue(NULL, szPriv, &tkp.Privileges[0].Luid);
  647. }
  648. if (bLookup)
  649. {
  650. tkp.PrivilegeCount = 1;
  651. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  652. // Clear the last error.
  653. SetLastError(0);
  654. // Turn it on
  655. bRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
  656. (PTOKEN_PRIVILEGES) NULL, 0);
  657. dwLastError = GetLastError();
  658. }
  659. CloseHandle(hToken);
  660. }
  661. // We have to check GetLastError() because AdjustTokenPrivileges lies about
  662. // its success but GetLastError() doesn't.
  663. return bRet && dwLastError == ERROR_SUCCESS;
  664. }
  665. // Takes a pnp id and returns a bios unit number
  666. // To avoid frequent load/unload of a library, the pGetWin9XBiosUnit parameter comes from:
  667. // HINSTANCE hInst = LoadLibrary("cim32net.dll");
  668. // pGetWin9XBiosUnit = (fnGetWin9XBiosUnit)GetProcAddress(hInst, "GetWin9XBiosUnit");
  669. BYTE GetBiosUnitNumberFromPNPID(fnGetWin9XBiosUnit pGetWin9XBiosUnit, CHString strDeviceID)
  670. {
  671. CHString sTemp;
  672. DRIVE_MAP_INFO stDMI;
  673. CRegistry Reg1;
  674. BYTE btBiosUnit = -1;
  675. // Open the associated registry key
  676. if (Reg1.Open(HKEY_LOCAL_MACHINE, "enum\\" + strDeviceID, KEY_QUERY_VALUE) == ERROR_SUCCESS)
  677. {
  678. // Get a drive letter for this pnp id
  679. if ((Reg1.GetCurrentKeyValue("CurrentDriveLetterAssignment", sTemp) != ERROR_SUCCESS) ||
  680. (sTemp.GetLength() == 0)) {
  681. // No drive letters, let's try one more thing. On memphis sp1, this call will also
  682. // get us a unit number.
  683. if (pGetWin9XBiosUnit != NULL)
  684. {
  685. btBiosUnit = pGetWin9XBiosUnit(strDeviceID.GetBuffer(0));
  686. }
  687. }
  688. else
  689. {
  690. if (GetDriveMapInfo(&stDMI, toupper(sTemp[0]) - 'A' + 1))
  691. {
  692. btBiosUnit = stDMI.btInt13Unit;
  693. }
  694. }
  695. }
  696. return btBiosUnit;
  697. }
  698. HRESULT GetHKUserNames(CHStringList &list)
  699. {
  700. HRESULT hres;
  701. // Empty the list.
  702. list.clear();
  703. if (GetPlatformID() == VER_PLATFORM_WIN32_NT)
  704. {
  705. // Enum the profiles from the registry.
  706. CRegistry regProfileList;
  707. CHString strProfile;
  708. DWORD dwErr;
  709. // Open the ProfileList key so we know which profiles to load up.
  710. if ((dwErr = regProfileList.OpenAndEnumerateSubKeys(
  711. HKEY_LOCAL_MACHINE,
  712. IDS_RegNTProfileList,
  713. KEY_READ)) == ERROR_SUCCESS)
  714. {
  715. for (int i = 0; regProfileList.GetCurrentSubKeyName(strProfile) ==
  716. ERROR_SUCCESS; i++)
  717. {
  718. list.push_back(strProfile);
  719. regProfileList.NextSubKey();
  720. }
  721. }
  722. // Add the .DEFAULT name.
  723. list.push_back(_T(".DEFAULT"));
  724. hres = WinErrorToWBEMhResult(dwErr);
  725. }
  726. else
  727. {
  728. DWORD dwErr = ERROR_SUCCESS;
  729. #ifdef _DEBUG
  730. DWORD dwSize = 10,
  731. #else
  732. DWORD dwSize = 1024,
  733. #endif
  734. dwBytesRead;
  735. TCHAR *szBuff = NULL;
  736. // Keep looping until we read the entire section.
  737. // You know your buffer wasn't big enough if the returned number
  738. // of bytes == (size passed in - 2).
  739. do
  740. {
  741. if (szBuff)
  742. {
  743. free(szBuff);
  744. dwSize *= 2;
  745. }
  746. szBuff = (TCHAR *) malloc(dwSize);
  747. // Out of memory. Get out of loop.
  748. if (!szBuff)
  749. break;
  750. dwBytesRead =
  751. GetPrivateProfileString(
  752. "Password Lists",
  753. NULL,
  754. "",
  755. szBuff,
  756. dwSize,
  757. "system.ini");
  758. } while (dwBytesRead >= dwSize - 2);
  759. if (szBuff)
  760. {
  761. // Loop through the list of names. Each is null-terminated, and the
  762. // list is terminated with a double null.
  763. TCHAR *pszCurrent = szBuff;
  764. while (*pszCurrent)
  765. {
  766. list.push_back(pszCurrent);
  767. pszCurrent += lstrlen(pszCurrent) + 1;
  768. }
  769. hres = WBEM_S_NO_ERROR;
  770. // Free the buffer.
  771. free(szBuff);
  772. // Add the .DEFAULT name.
  773. list.push_back(_T(".DEFAULT"));
  774. }
  775. else
  776. // Failed to malloc, so set error code.
  777. hres = WBEM_E_OUT_OF_MEMORY;
  778. }
  779. return hres;
  780. }
  781. VOID EscapeBackslashes(CHString& chstrIn,
  782. CHString& chstrOut)
  783. {
  784. CHString chstrCpyNormPathname = chstrIn;
  785. LONG lNext = -1L;
  786. chstrOut.Empty();
  787. // Find the next '\'
  788. lNext = chstrCpyNormPathname.Find(_T('\\'));
  789. while(lNext != -1)
  790. {
  791. // Add on to the new string we are building:
  792. chstrOut += chstrCpyNormPathname.Left(lNext + 1);
  793. // Add on the second backslash:
  794. chstrOut += _T('\\');
  795. // Hack off from the input string the portion we just copied
  796. chstrCpyNormPathname = chstrCpyNormPathname.Right(chstrCpyNormPathname.GetLength() - lNext - 1);
  797. lNext = chstrCpyNormPathname.Find(_T('\\'));
  798. }
  799. // If the last character wasn't a '\', there may still be leftovers, so
  800. // copy them here.
  801. if(chstrCpyNormPathname.GetLength() != 0)
  802. {
  803. chstrOut += chstrCpyNormPathname;
  804. }
  805. }
  806. VOID EscapeQuotes(CHString& chstrIn,
  807. CHString& chstrOut)
  808. {
  809. CHString chstrCpyNormPathname = chstrIn;
  810. LONG lNext = -1L;
  811. chstrOut.Empty();
  812. // Find the next '\'
  813. lNext = chstrCpyNormPathname.Find(_T('\"'));
  814. while(lNext != -1)
  815. {
  816. // Add on to the new string we are building:
  817. chstrOut += chstrCpyNormPathname.Left(lNext);
  818. // Escape the quote:
  819. chstrOut += _T("\\\"");
  820. // Hack off from the input string the portion we just copied
  821. chstrCpyNormPathname = chstrCpyNormPathname.Right(chstrCpyNormPathname.GetLength() - lNext - 1);
  822. lNext = chstrCpyNormPathname.Find(_T('\"'));
  823. }
  824. // If the last character wasn't a '\', there may still be leftovers, so
  825. // copy them here.
  826. if(chstrCpyNormPathname.GetLength() != 0)
  827. {
  828. chstrOut += chstrCpyNormPathname;
  829. }
  830. }
  831. VOID RemoveDoubleBackslashes(const CHString& chstrIn, CHString& chstrOut)
  832. {
  833. CHString chstrBuildString;
  834. CHString chstrInCopy = chstrIn;
  835. BOOL fDone = FALSE;
  836. LONG lPos = -1;
  837. while(!fDone)
  838. {
  839. lPos = chstrInCopy.Find(_T("\\\\"));
  840. if(lPos != -1)
  841. {
  842. chstrBuildString += chstrInCopy.Left(lPos);
  843. chstrBuildString += _T("\\");
  844. chstrInCopy = chstrInCopy.Mid(lPos+2);
  845. }
  846. else
  847. {
  848. chstrBuildString += chstrInCopy;
  849. fDone = TRUE;
  850. }
  851. }
  852. chstrOut = chstrBuildString;
  853. }
  854. CHString RemoveDoubleBackslashes(const CHString& chstrIn)
  855. {
  856. CHString chstrBuildString;
  857. CHString chstrInCopy = chstrIn;
  858. BOOL fDone = FALSE;
  859. LONG lPos = -1;
  860. while(!fDone)
  861. {
  862. lPos = chstrInCopy.Find(_T("\\\\"));
  863. if(lPos != -1)
  864. {
  865. chstrBuildString += chstrInCopy.Left(lPos);
  866. chstrBuildString += _T("\\");
  867. chstrInCopy = chstrInCopy.Mid(lPos+2);
  868. }
  869. else
  870. {
  871. chstrBuildString += chstrInCopy;
  872. fDone = TRUE;
  873. }
  874. }
  875. return chstrBuildString;
  876. }