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.

2178 lines
55 KiB

  1. //=================================================================
  2. //
  3. // DllUtils.cpp
  4. //
  5. // Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
  6. //
  7. //=================================================================
  8. #include "precomp.h"
  9. #include <cregcls.h>
  10. #include <assertbreak.h>
  11. #include <lockwrap.h>
  12. #include <lmerr.h>
  13. #include <CCriticalSec.h>
  14. #include <CAutoLock.h>
  15. #include "dllmain.h"
  16. #ifdef WIN9XONLY
  17. #include <win32thk.h>
  18. #endif
  19. #include <CRegCls.h>
  20. #include <delayimp.h>
  21. #define UNRECOGNIZED_VARIANT_TYPE FALSE
  22. DWORD g_dwMajorVersion,
  23. g_dwMinorVersion,
  24. g_dwBuildNumber;
  25. CCriticalSec g_CSFlakyFileVersionAPI;
  26. // There is a problem with loading Cim32Net.dll over and over, so this code
  27. // makes sure we only load it once, then unloads it at exit.
  28. // these are used with GetCim32NetHandle
  29. #ifdef WIN9XONLY
  30. HoldSingleCim32NetPtr::HoldSingleCim32NetPtr()
  31. {
  32. }
  33. // Initialize the static members
  34. HINSTANCE HoldSingleCim32NetPtr::m_spCim32NetApiHandle = NULL;
  35. CCritSec HoldSingleCim32NetPtr::m_csCim32Net;
  36. HoldSingleCim32NetPtr::~HoldSingleCim32NetPtr()
  37. {
  38. // FreeCim32NetApiPtr();
  39. }
  40. void HoldSingleCim32NetPtr::FreeCim32NetApiPtr()
  41. {
  42. CLockWrapper Cim32NetLock( m_csCim32Net ) ;
  43. if (m_spCim32NetApiHandle)
  44. {
  45. FreeLibrary ( m_spCim32NetApiHandle );
  46. m_spCim32NetApiHandle = NULL;
  47. }
  48. }
  49. CCim32NetApi* HoldSingleCim32NetPtr::GetCim32NetApiPtr()
  50. {
  51. CCim32NetApi* pNewCim32NetApi = NULL ;
  52. {
  53. // Avoid contention on static
  54. CLockWrapper Cim32NetLock( m_csCim32Net ) ;
  55. // Check for race condition
  56. if (m_spCim32NetApiHandle == NULL)
  57. {
  58. m_spCim32NetApiHandle = LoadLibrary ( "Cim32Net.dll" ) ;
  59. }
  60. if (m_spCim32NetApiHandle != NULL)
  61. {
  62. pNewCim32NetApi = (CCim32NetApi*) CResourceManager::sm_TheResourceManager.GetResource(g_guidCim32NetApi, NULL);
  63. }
  64. else
  65. {
  66. LogErrorMessage2(L"Failed to loadlibrary Cim32Net.dll (0x%x)", GetLastError());
  67. }
  68. }
  69. return pNewCim32NetApi;
  70. }
  71. HoldSingleCim32NetPtr g_GlobalInstOfHoldSingleCim32NetPtr;
  72. #endif
  73. class CInitDllUtilsData
  74. {
  75. public:
  76. CInitDllUtilsData();
  77. };
  78. CInitDllUtilsData::CInitDllUtilsData()
  79. {
  80. OSVERSIONINFO version = { sizeof(version) };
  81. GetVersionEx((LPOSVERSIONINFO) &version);
  82. g_dwMajorVersion = version.dwMajorVersion;
  83. g_dwMinorVersion = version.dwMinorVersion;
  84. g_dwBuildNumber = version.dwBuildNumber;
  85. }
  86. // So we can cache OS info automatically.
  87. static CInitDllUtilsData dllUtilsData;
  88. #ifdef NTONLY
  89. // sets a status object with one single missing privilege
  90. void WINAPI SetSinglePrivilegeStatusObject(MethodContext* pContext, const WCHAR* pPrivilege)
  91. {
  92. SAFEARRAY *psaPrivilegesReqd, *psaPrivilegesNotHeld;
  93. SAFEARRAYBOUND rgsabound[1];
  94. rgsabound[0].cElements = 1;
  95. rgsabound[0].lLbound = 0;
  96. psaPrivilegesReqd = SafeArrayCreate(VT_BSTR, 1, rgsabound);
  97. psaPrivilegesNotHeld = SafeArrayCreate(VT_BSTR, 1, rgsabound);
  98. if (psaPrivilegesReqd && psaPrivilegesNotHeld)
  99. {
  100. try
  101. {
  102. long index = 0;
  103. bstr_t privilege(pPrivilege);
  104. if(SUCCEEDED(SafeArrayPutElement(psaPrivilegesReqd, &index, (void*)(BSTR)privilege)))
  105. if(SUCCEEDED(SafeArrayPutElement(psaPrivilegesNotHeld, &index, (void*)(BSTR)privilege)))
  106. {
  107. CWbemProviderGlue::SetStatusObject(pContext, IDS_CimWin32Namespace,
  108. L"Required privilege not enabled", WBEM_E_FAILED, psaPrivilegesNotHeld, psaPrivilegesReqd);
  109. }
  110. }
  111. catch ( ... )
  112. {
  113. SafeArrayDestroy(psaPrivilegesNotHeld);
  114. SafeArrayDestroy(psaPrivilegesReqd);
  115. throw ;
  116. }
  117. SafeArrayDestroy(psaPrivilegesNotHeld);
  118. SafeArrayDestroy(psaPrivilegesReqd);
  119. }
  120. else
  121. {
  122. if (psaPrivilegesNotHeld)
  123. SafeArrayDestroy(psaPrivilegesNotHeld);
  124. if (psaPrivilegesReqd)
  125. SafeArrayDestroy(psaPrivilegesReqd);
  126. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  127. }
  128. }
  129. #endif
  130. DWORD WINAPI GetPlatformBuildNumber(void)
  131. {
  132. return g_dwBuildNumber;
  133. }
  134. // 3 for NT 3.51
  135. // 4 for NT 4.0, W95 & W98
  136. DWORD WINAPI GetPlatformMajorVersion(void)
  137. {
  138. return g_dwMajorVersion;
  139. }
  140. // 0 for W95, 10 for 98
  141. DWORD WINAPI GetPlatformMinorVersion(void)
  142. {
  143. return g_dwMajorVersion;
  144. }
  145. #ifdef WIN9XONLY
  146. // returns TRUE iff the current OS is Win 98+
  147. // false for NT or Win 95
  148. bool WINAPI IsWin95(void)
  149. {
  150. return g_dwMinorVersion == 0;
  151. }
  152. bool WINAPI IsWin98(void)
  153. {
  154. return g_dwMinorVersion >= 10;
  155. }
  156. bool WINAPI IsMillennium(void)
  157. {
  158. return g_dwMinorVersion >= 90;
  159. }
  160. #endif
  161. #ifdef NTONLY
  162. bool WINAPI IsWinNT52(void)
  163. {
  164. return (g_dwMajorVersion >= 5 && g_dwMinorVersion == 2);
  165. }
  166. bool WINAPI IsWinNT51(void)
  167. {
  168. return (g_dwMajorVersion >= 5 && g_dwMinorVersion == 1);
  169. }
  170. bool WINAPI IsWinNT5(void)
  171. {
  172. return g_dwMajorVersion >= 5;
  173. }
  174. bool WINAPI IsWinNT4(void)
  175. {
  176. return g_dwMajorVersion == 4;
  177. }
  178. bool WINAPI IsWinNT351(void)
  179. {
  180. return g_dwMajorVersion == 3 && g_dwMinorVersion == 51;
  181. }
  182. #endif
  183. /////////////////////////////////////////////////////////////////////
  184. void WINAPI LogEnumValueError( LPCWSTR szFile, DWORD dwLine, LPCWSTR szKey, LPCWSTR szId )
  185. {
  186. if (IsErrorLoggingEnabled())
  187. {
  188. CHString gazotta;
  189. gazotta.Format(ERR_REGISTRY_ENUM_VALUE_FOR_KEY, szId, szKey);
  190. LogErrorMessageEx(gazotta, szFile, dwLine);
  191. }
  192. }
  193. /////////////////////////////////////////////////////////////////////
  194. void WINAPI LogOpenRegistryError( LPCWSTR szFile, DWORD dwLine, LPCWSTR szKey )
  195. {
  196. if (IsErrorLoggingEnabled())
  197. {
  198. CHString gazotta;
  199. gazotta.Format(ERR_OPEN_REGISTRY, szKey);
  200. LogErrorMessageEx(gazotta, szFile, dwLine);
  201. }
  202. }
  203. /////////////////////////////////////////////////////////////////////
  204. // left in for hysterical purposes
  205. // prefer to use LogMessage macro in BrodCast.h
  206. //void LogError( char * szFile, DWORD dwLine, char * szKey )
  207. //{
  208. // LogErrorMessageEx(szKey, szFile, dwLine);
  209. //}
  210. /////////////////////////////////////////////////////////////////////
  211. void WINAPI LogLastError( LPCTSTR szFile, DWORD dwLine )
  212. {
  213. if (IsErrorLoggingEnabled())
  214. {
  215. DWORD duhWord = GetLastError();
  216. CHString gazotta;
  217. gazotta.Format(IDS_GETLASTERROR, duhWord, duhWord);
  218. LogErrorMessageEx(gazotta, TOBSTRT(szFile), dwLine);
  219. }
  220. }
  221. ///////////////////////////////////////////////////////////////////////
  222. BOOL WINAPI GetValue( CRegistry & Reg,
  223. LPCWSTR szKey,
  224. LPCWSTR ValueName,
  225. CHString * pchsValueBuffer )
  226. {
  227. BOOL bRet = (Reg.GetCurrentKeyValue( ValueName, *pchsValueBuffer) == ERROR_SUCCESS);
  228. if( !bRet )
  229. LogEnumValueError(_T2(__FILE__), __LINE__, szKey, ValueName);
  230. return bRet;
  231. }
  232. ///////////////////////////////////////////////////////////////////////
  233. BOOL WINAPI GetValue( CRegistry & Reg,
  234. LPCWSTR szKey,
  235. LPCWSTR ValueName,
  236. DWORD * dwValueBuffer )
  237. {
  238. BOOL bRet = (Reg.GetCurrentKeyValue( ValueName, *dwValueBuffer) == ERROR_SUCCESS);
  239. if( !bRet )
  240. LogEnumValueError(_T2(__FILE__),__LINE__, TOBSTRT(szKey), TOBSTRT(ValueName));
  241. return bRet;
  242. }
  243. ///////////////////////////////////////////////////////////////////////
  244. BOOL WINAPI OpenAndGetValue( CRegistry & Reg,
  245. LPCWSTR szKey,
  246. LPCWSTR ValueName,
  247. CHString * pchsValueBuffer )
  248. {
  249. BOOL bRet = ( Reg.OpenLocalMachineKeyAndReadValue( szKey, ValueName, *pchsValueBuffer )== ERROR_SUCCESS);
  250. if( !bRet )
  251. LogEnumValueError(_T2(__FILE__),__LINE__, szKey, ValueName);
  252. return bRet;
  253. }
  254. ///////////////////////////////////////////////////////////////////////
  255. BOOL WINAPI GetBinaryValue( CRegistry & Reg, LPCWSTR szKey,
  256. LPCWSTR ValueName, CHString * pchsValueBuffer )
  257. {
  258. BOOL bRet = ( Reg.GetCurrentBinaryKeyValue( ValueName, *pchsValueBuffer) == ERROR_SUCCESS);
  259. if( !bRet )
  260. (LogEnumValueError(_T2(__FILE__),__LINE__, szKey, ValueName));
  261. return bRet;
  262. }
  263. /*****************************************************************************
  264. *
  265. * FUNCTION : GetDeviceParms
  266. *
  267. * DESCRIPTION : Gets drive characteristics (heads, tracks, cylinders, etc)
  268. *
  269. * INPUTS : Pointer to a DEVICEPARMS struct to receive the data
  270. * Drive number of the drive to query (0 = default drive,
  271. * 1 = A, 2 = B, and so on)
  272. *
  273. * OUTPUTS :
  274. *
  275. * RETURNS : TRUE if successful, FALSE otherwise
  276. *
  277. * COMMENTS :
  278. *
  279. *****************************************************************************/
  280. #ifdef WIN9XONLY
  281. BOOL WINAPI GetDeviceParms(PDEVICEPARMS pstDeviceParms, UINT nDrive)
  282. {
  283. DEVIOCTL_REGISTERS reg;
  284. memset(&reg, '\0', sizeof(DEVIOCTL_REGISTERS));
  285. reg.reg_EAX = 0x440D; /* IOCTL for block devices */
  286. reg.reg_EBX = nDrive; /* zero-based drive ID */
  287. reg.reg_ECX = 0x0860; /* Get Media ID command */
  288. reg.reg_EDX = (DWORD) pstDeviceParms;
  289. memset(pstDeviceParms, 0, sizeof(DEVICEPARMS));
  290. if (!VWIN32IOCTL(&reg, VWIN32_DIOC_DOS_IOCTL))
  291. return FALSE;
  292. if (reg.reg_Flags & 0x8000) /* error if carry flag set */
  293. return FALSE;
  294. // While the docs say failure will set carry, experience shows
  295. // this isn't true. So, if carry is clear, and ax is zero, we'll
  296. // assume that things are ok.
  297. if (reg.reg_EAX == 0)
  298. return TRUE;
  299. // If they didn't change the value, we'll assume that they followed
  300. // the spec and are correctly setting carry.
  301. if (reg.reg_EAX == 0x440d)
  302. return TRUE;
  303. // Otherwise, assume they are incorrectly setting carry, and have returned
  304. // a failure code.
  305. return FALSE;
  306. }
  307. #endif
  308. /*****************************************************************************
  309. *
  310. * FUNCTION : GetDeviceParmsFat32
  311. *
  312. * DESCRIPTION : Gets drive characteristics (heads, tracks, cylinders, etc)
  313. * for Fat32 drives.
  314. *
  315. * INPUTS : Pointer to a EA_DEVICEPARMS struct to receive the data
  316. * Drive number of the drive to query (0 = default drive,
  317. * 1 = A, 2 = B, and so on)
  318. *
  319. * OUTPUTS :
  320. *
  321. * RETURNS : TRUE if successful, FALSE otherwise
  322. *
  323. * COMMENTS :
  324. *
  325. *****************************************************************************/
  326. #ifdef WIN9XONLY
  327. BOOL WINAPI GetDeviceParmsFat32(PEA_DEVICEPARAMETERS pstDeviceParms, UINT nDrive)
  328. {
  329. DEVIOCTL_REGISTERS reg;
  330. memset(&reg, '\0', sizeof(DEVIOCTL_REGISTERS));
  331. reg.reg_EAX = 0x440D; /* IOCTL for block devices */
  332. reg.reg_EBX = nDrive; /* zero-based drive ID */
  333. reg.reg_ECX = 0x4860; /* Get Media ID command */
  334. reg.reg_EDX = (DWORD) pstDeviceParms;
  335. memset(pstDeviceParms, 0, sizeof(EA_DEVICEPARAMETERS));
  336. if (!VWIN32IOCTL(&reg, VWIN32_DIOC_DOS_IOCTL))
  337. return FALSE;
  338. if (reg.reg_Flags & 0x8000) /* error if carry flag set */
  339. return FALSE;
  340. return TRUE;
  341. }
  342. #endif
  343. /*****************************************************************************
  344. *
  345. * FUNCTION : GetDriveMapInfo
  346. *
  347. * DESCRIPTION : Gets logical to physical mapping info
  348. *
  349. * INPUTS : Pointer to a DRIVE_MAP_INFO struct to receive the data
  350. * Drive number of the drive to query (0 = default drive,
  351. * 1 = A, 2 = B, and so on)
  352. *
  353. * OUTPUTS :
  354. *
  355. * RETURNS : TRUE if successful, FALSE otherwise
  356. *
  357. * COMMENTS :
  358. *
  359. *****************************************************************************/
  360. #ifdef WIN9XONLY
  361. BOOL WINAPI GetDriveMapInfo(PDRIVE_MAP_INFO pDriveMapInfo, UINT nDrive)
  362. {
  363. DEVIOCTL_REGISTERS reg;
  364. memset(&reg, '\0', sizeof(DEVIOCTL_REGISTERS));
  365. reg.reg_EAX = 0x440d; /* IOCTL for block devices */
  366. reg.reg_EBX = nDrive; /* zero-based drive ID */
  367. reg.reg_ECX = 0x086f; /* Get Drive Map Info */
  368. reg.reg_EDX = (DWORD) pDriveMapInfo;
  369. // zero the struct
  370. memset(pDriveMapInfo, 0, sizeof(DRIVE_MAP_INFO));
  371. // Set the length byte
  372. pDriveMapInfo->btAllocationLength = sizeof(DRIVE_MAP_INFO);
  373. // Doit
  374. if (!VWIN32IOCTL(&reg, VWIN32_DIOC_DOS_IOCTL))
  375. return FALSE;
  376. if (reg.reg_Flags & 0x8000) {/* error if carry flag set */
  377. return FALSE;
  378. }
  379. return TRUE;
  380. }
  381. #endif
  382. /*****************************************************************************
  383. *
  384. * FUNCTION : Get_ExtFreeSpace
  385. *
  386. * DESCRIPTION : Gets detailed info about a partition
  387. *
  388. * INPUTS : Drive number of the drive to query (0 = default drive,
  389. * 1 = A, 2 = B, and so on)
  390. * Pointer to ExtGetDskFreSpcStruct
  391. *
  392. * OUTPUTS :
  393. *
  394. * RETURNS : TRUE if successful, FALSE otherwise
  395. *
  396. * COMMENTS :
  397. *
  398. *****************************************************************************/
  399. #ifdef WIN9XONLY
  400. BOOL WINAPI Get_ExtFreeSpace(BYTE btDriveName, ExtGetDskFreSpcStruc *pstExtGetDskFreSpcStruc)
  401. {
  402. DEVIOCTL_REGISTERS reg;
  403. memset(&reg, '\0', sizeof(DEVIOCTL_REGISTERS));
  404. char szDrive[4];
  405. szDrive[0] = btDriveName;
  406. szDrive[1] = ':';
  407. szDrive[2] = '\\';
  408. szDrive[3] = '\0';
  409. reg.reg_EAX = 0x7303; // Get_ExtFreeSpace
  410. reg.reg_ECX = sizeof(ExtGetDskFreSpcStruc); // Size of the structure sent in
  411. reg.reg_EDI = (DWORD)pstExtGetDskFreSpcStruc; // Structure
  412. reg.reg_EDX = (DWORD)szDrive; // Drive to get info for
  413. // zero the struct
  414. memset(pstExtGetDskFreSpcStruc, 0, sizeof(ExtGetDskFreSpcStruc));
  415. // Doit
  416. if (!VWIN32IOCTL(&reg, VWIN32_DIOC_DOS_DRIVEINFO))
  417. return FALSE;
  418. if (reg.reg_Flags & 0x8000) {/* error if carry flag set */
  419. return FALSE;
  420. }
  421. return TRUE;
  422. }
  423. #endif
  424. /*****************************************************************************
  425. *
  426. * FUNCTION : VWIN32IOCTL
  427. *
  428. * DESCRIPTION : Calls IOControl against the vwin32 vxd
  429. *
  430. * INPUTS : Pointer to DEVIOCTL_REGISTERS structure
  431. * IOControl call number.
  432. *
  433. * OUTPUTS :
  434. *
  435. * RETURNS : TRUE if successful, FALSE otherwise
  436. *
  437. * COMMENTS :
  438. *
  439. *****************************************************************************/
  440. #ifdef WIN9XONLY
  441. BOOL WINAPI VWIN32IOCTL(PDEVIOCTL_REGISTERS preg, DWORD dwCall)
  442. {
  443. BOOL fResult;
  444. DWORD cb;
  445. preg->reg_Flags = 0x8000; /* assume error (carry flag set) */
  446. SmartCloseHandle hDevice = CreateFile(_T("\\\\.\\VWIN32"), 0, 0, 0, OPEN_EXISTING,
  447. FILE_FLAG_DELETE_ON_CLOSE, 0);
  448. if (hDevice == (HANDLE) INVALID_HANDLE_VALUE)
  449. {
  450. return FALSE;
  451. }
  452. else
  453. {
  454. fResult = DeviceIoControl(hDevice, dwCall, preg, sizeof(*preg), preg, sizeof(*preg), &cb, 0);
  455. }
  456. if (!fResult)
  457. {
  458. return FALSE;
  459. }
  460. return TRUE;
  461. }
  462. #endif
  463. CHString WINAPI GetFileTypeDescription(LPCTSTR szExtension)
  464. {
  465. CRegistry RegInfo;
  466. CHString sTemp, sType(szExtension);
  467. if (RegInfo.Open(HKEY_CLASSES_ROOT, TOBSTRT(szExtension), KEY_READ) == ERROR_SUCCESS) {
  468. RegInfo.GetCurrentKeyValue(L"", sTemp);
  469. if (RegInfo.Open(HKEY_CLASSES_ROOT, sTemp, KEY_READ) == ERROR_SUCCESS) {
  470. RegInfo.GetCurrentKeyValue(L"", sType);
  471. }
  472. }
  473. return sType;
  474. }
  475. void WINAPI ConfigStatusToCimStatus ( DWORD a_Status , CHString &a_StringStatus )
  476. {
  477. if( a_Status & DN_ROOT_ENUMERATED ||
  478. a_Status & DN_DRIVER_LOADED ||
  479. a_Status & DN_ENUM_LOADED ||
  480. a_Status & DN_STARTED )
  481. {
  482. a_StringStatus = IDS_STATUS_OK;
  483. }
  484. // we don't care about these:
  485. // DN_MANUAL,DN_NOT_FIRST_TIME,DN_HARDWARE_ENUM,DN_FILTERED
  486. // DN_DISABLEABLE, DN_REMOVABLE,DN_MF_PARENT,DN_MF_CHILD
  487. // DN_NEED_TO_ENUM, DN_LIAR,DN_HAS_MARK
  488. if( a_Status & DN_MOVED ||
  489. a_Status & DN_WILL_BE_REMOVED)
  490. {
  491. a_StringStatus = IDS_STATUS_Degraded;
  492. }
  493. if( a_Status & DN_HAS_PROBLEM ||
  494. a_Status & DN_PRIVATE_PROBLEM)
  495. {
  496. a_StringStatus = IDS_STATUS_Error;
  497. }
  498. }
  499. #ifdef NTONLY
  500. ///////////////////////////////////////////////////////////////////
  501. //
  502. // Define the severity codes
  503. //
  504. // Sev - is the severity code
  505. //
  506. // 00 - Success
  507. // 01 - Informational
  508. // 10 - Warning
  509. // 11 - Error
  510. //
  511. // Define the severity codes
  512. //
  513. //
  514. // Define the severity codes
  515. //
  516. #define STATUS_SEVERITY_WARNING 0x2
  517. #define STATUS_SEVERITY_SUCCESS 0x0
  518. #define STATUS_SEVERITY_INFORMATIONAL 0x1
  519. #define STATUS_SEVERITY_ERROR 0x3
  520. #define SEV_MASK 0xC0000000
  521. void WINAPI TranslateNTStatus( DWORD dwStatus, CHString & chsValue)
  522. {
  523. switch((dwStatus & SEV_MASK) >> 30){
  524. case STATUS_SEVERITY_WARNING:
  525. chsValue = IDS_STATUS_Degraded;
  526. break;
  527. case STATUS_SEVERITY_SUCCESS:
  528. chsValue = IDS_STATUS_OK;
  529. break;
  530. case STATUS_SEVERITY_ERROR:
  531. chsValue = IDS_STATUS_Error;
  532. break;
  533. case STATUS_SEVERITY_INFORMATIONAL:
  534. chsValue = IDS_STATUS_OK;
  535. break;
  536. default:
  537. chsValue = IDS_STATUS_Unknown;
  538. }
  539. }
  540. #endif
  541. //
  542. #ifdef NTONLY
  543. bool WINAPI GetServiceStatus( CHString a_chsService, CHString &a_chsStatus )
  544. {
  545. bool t_bRet = false ;
  546. SC_HANDLE t_hDBHandle = NULL ;
  547. SC_HANDLE t_hSvcHandle = NULL ;
  548. try
  549. {
  550. if( t_hDBHandle = OpenSCManager( NULL, NULL, GENERIC_READ ) )
  551. {
  552. t_bRet = true ;
  553. if( t_hSvcHandle = OpenService (
  554. t_hDBHandle,
  555. a_chsService,
  556. SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_INTERROGATE ) )
  557. {
  558. SERVICE_STATUS t_StatusInfo ;
  559. if ( ControlService( t_hSvcHandle, SERVICE_CONTROL_INTERROGATE, &t_StatusInfo ) )
  560. {
  561. switch( t_StatusInfo.dwCurrentState )
  562. {
  563. case SERVICE_STOPPED:
  564. {
  565. a_chsStatus = L"Degraded" ;
  566. }
  567. break ;
  568. case SERVICE_START_PENDING:
  569. {
  570. a_chsStatus = L"Starting" ;
  571. }
  572. break ;
  573. case SERVICE_STOP_PENDING:
  574. {
  575. a_chsStatus = L"Stopping" ;
  576. }
  577. break ;
  578. case SERVICE_RUNNING:
  579. case SERVICE_PAUSE_PENDING:
  580. {
  581. a_chsStatus = L"OK" ;
  582. }
  583. break ;
  584. case SERVICE_PAUSED:
  585. case SERVICE_CONTINUE_PENDING:
  586. {
  587. a_chsStatus = L"Degraded" ;
  588. }
  589. break ;
  590. }
  591. }
  592. else
  593. {
  594. a_chsStatus = L"Unknown" ;
  595. }
  596. CloseServiceHandle( t_hSvcHandle ) ;
  597. t_hSvcHandle = NULL ;
  598. }
  599. else
  600. {
  601. a_chsStatus = L"Unknown" ;
  602. }
  603. CloseServiceHandle( t_hDBHandle ) ;
  604. t_hDBHandle = NULL ;
  605. }
  606. }
  607. catch( ... )
  608. {
  609. if( t_hSvcHandle )
  610. {
  611. CloseServiceHandle( t_hSvcHandle ) ;
  612. }
  613. if( t_hDBHandle )
  614. {
  615. CloseServiceHandle( t_hDBHandle ) ;
  616. }
  617. throw ;
  618. }
  619. return t_bRet ;
  620. }
  621. #endif
  622. //
  623. bool WINAPI GetFileInfoBlock(LPCTSTR szFile, LPVOID *pInfo)
  624. {
  625. BOOL fRet = false;
  626. DWORD dwTemp,
  627. dwBlockSize;
  628. LPVOID pInfoTemp = NULL;
  629. if(pInfo != NULL)
  630. {
  631. try
  632. {
  633. CAutoLock cs(g_CSFlakyFileVersionAPI);
  634. dwBlockSize = GetFileVersionInfoSize((LPTSTR) szFile, &dwTemp);
  635. if(dwBlockSize)
  636. {
  637. pInfoTemp = (LPVOID) new BYTE[dwBlockSize + 4];
  638. if(pInfoTemp != NULL)
  639. {
  640. memset( pInfoTemp, NULL, dwBlockSize + 4);
  641. if (GetFileVersionInfo((LPTSTR) szFile, 0, dwBlockSize, pInfoTemp))
  642. {
  643. *pInfo = pInfoTemp;
  644. fRet = true;
  645. }
  646. }
  647. else
  648. {
  649. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  650. }
  651. }
  652. }
  653. catch(...)
  654. {
  655. // We don't need to do anything else, just need to protect ourselves
  656. // from the flaky version.dll calls.
  657. }
  658. }
  659. return fRet;
  660. }
  661. bool WINAPI GetVarFromInfoBlock(LPVOID pInfo, LPCTSTR szVar, CHString &strValue)
  662. {
  663. bool fRet = false;
  664. try
  665. {
  666. if(pInfo != NULL)
  667. {
  668. WORD wLang = 0;
  669. WORD wCodePage = 0;
  670. UINT len;
  671. if(!GetVersionLanguage(pInfo, &wLang, &wCodePage) )
  672. {
  673. // on failure: default to English
  674. // this returns a pointer to an array of WORDs
  675. WORD *pArray;
  676. if (VerQueryValue(pInfo, _T("\\VarFileInfo\\Translation"), (void **)(&pArray), &len))
  677. {
  678. len = len / sizeof(WORD);
  679. // find the english one...
  680. for (int i = 0; i < len; i += 2)
  681. {
  682. if( pArray[i] == 0x0409 )
  683. {
  684. wLang = pArray[i];
  685. wCodePage = pArray[i + 1];
  686. break;
  687. }
  688. }
  689. }
  690. }
  691. TCHAR *pMfg;
  692. TCHAR szTemp[256];
  693. StringCchPrintf(szTemp,LENGTH_OF(szTemp), _T("\\StringFileInfo\\%04X%04X\\%s"), wLang, wCodePage, szVar);
  694. if( VerQueryValue(pInfo, szTemp, (void **)(&pMfg), &len))
  695. {
  696. strValue = pMfg;
  697. fRet = true;
  698. }
  699. }
  700. }
  701. catch(...)
  702. {
  703. // We don't need to do anything else, just need to protect ourselves
  704. // from the flaky version.dll calls.
  705. }
  706. return fRet;
  707. }
  708. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  709. Function: BOOL GetVersionLanguage(void *vpInfo,
  710. WORD *wpLang,
  711. WORD *wpCodePage);
  712. Description: This function extracts the language and codepage out of a passed GetFileVersionInfo()
  713. result. Consideration is given to variation in the layout.
  714. Arguments: vpInfo, wpLang, wpCodePage
  715. Returns: Boolean
  716. Inputs:
  717. Outputs:
  718. Caveats:
  719. Courtesy of: SMS, Nick Dyer
  720. Raid:
  721. History: a-peterc 30-Oct-1998 Created
  722. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  723. BOOL WINAPI GetVersionLanguage(void *vpInfo, WORD *wpLang, WORD *wpCodePage)
  724. {
  725. BOOL bRet = FALSE;
  726. *wpLang = 0;
  727. *wpCodePage = 0;
  728. if ( vpInfo )
  729. {
  730. VERHEAD* pVerInfo = NULL;
  731. pVerInfo = (VERHEAD*) vpInfo;
  732. BYTE* ptr = NULL;
  733. ptr = (BYTE*) &pVerInfo->vsf;
  734. ptr = ptr + pVerInfo->wValLen;
  735. if ( pVerInfo->wType == 0 || pVerInfo->wType == 1 )
  736. {
  737. StringFileInfo* pStringFileInfo = NULL;
  738. pStringFileInfo = (StringFileInfo*) ptr;
  739. if ( pStringFileInfo->wValueLength == 0 )
  740. {
  741. if ( wcscmp(L"StringFileInfo",pStringFileInfo->szKey) == 0 )
  742. {
  743. // OK! were aligned properly
  744. StringTable* pStringTable = NULL;
  745. pStringTable = (StringTable*) &pStringFileInfo->Children;
  746. if ( pStringTable->wValueLength == 0 )
  747. {
  748. swscanf(pStringTable->szKey, L"%4x%4x", wpLang, wpCodePage);
  749. if ( *wpLang && *wpCodePage )
  750. {
  751. bRet = TRUE;
  752. }
  753. }
  754. }
  755. }
  756. }
  757. else
  758. {
  759. ptr = ptr+4;
  760. if ( strcmp("StringFileInfo",reinterpret_cast < char* > (ptr) ) == 0 )
  761. {
  762. // OK! were aligned properly
  763. ptr = ptr+20;
  764. sscanf(reinterpret_cast < char* > (ptr), "%4x%4x", wpLang, wpCodePage);
  765. if ( *wpLang && *wpCodePage )
  766. {
  767. bRet = TRUE;
  768. }
  769. }
  770. }
  771. }
  772. return (bRet);
  773. }
  774. ///////////////////////////////////////////////////////////////////
  775. bool WINAPI GetManufacturerFromFileName(LPCTSTR szFile, CHString &strMfg)
  776. {
  777. LPVOID lpv = NULL;
  778. bool fRet = false;
  779. try
  780. {
  781. if(GetFileInfoBlock(szFile, &lpv) && (lpv != NULL))
  782. {
  783. fRet = GetVarFromInfoBlock(lpv, _T("CompanyName"), strMfg);
  784. delete lpv;
  785. lpv = NULL;
  786. }
  787. }
  788. catch(...)
  789. {
  790. if(lpv != NULL)
  791. {
  792. delete lpv;
  793. lpv = NULL;
  794. }
  795. throw;
  796. }
  797. return fRet;
  798. }
  799. bool WINAPI GetVersionFromFileName(LPCTSTR szFile, CHString &strVersion)
  800. {
  801. LPVOID lpv = NULL;
  802. bool fRet = false;
  803. try
  804. {
  805. if(GetFileInfoBlock(szFile, &lpv) && (lpv != NULL))
  806. {
  807. fRet = GetVarFromInfoBlock(lpv, _T("ProductVersion"), strVersion);
  808. delete lpv;
  809. lpv = NULL;
  810. }
  811. }
  812. catch(...)
  813. {
  814. if(lpv != NULL)
  815. {
  816. delete lpv;
  817. lpv = NULL;
  818. }
  819. throw;
  820. }
  821. return fRet;
  822. }
  823. void WINAPI ReplaceString(CHString &str, LPCWSTR szFind, LPCWSTR szReplace)
  824. {
  825. int iWhere,
  826. nLen = lstrlenW(szFind);
  827. while ((iWhere = str.Find(szFind)) != -1)
  828. {
  829. str.Format(
  830. L"%s%s%s",
  831. (LPCWSTR) str.Left(iWhere),
  832. szReplace,
  833. (LPCWSTR) str.Mid(iWhere + nLen));
  834. }
  835. }
  836. #ifdef NTONLY
  837. BOOL WINAPI GetServiceFileName(LPCTSTR szService, CHString &strFileName)
  838. {
  839. SmartCloseServiceHandle hSCManager,
  840. hService;
  841. TCHAR szBuffer[2048];
  842. QUERY_SERVICE_CONFIG
  843. *pConfig = (QUERY_SERVICE_CONFIG *) szBuffer;
  844. DWORD dwNeeded;
  845. BOOL bRet = FALSE;
  846. hSCManager =
  847. OpenSCManager(
  848. NULL,
  849. NULL,
  850. STANDARD_RIGHTS_REQUIRED);
  851. if (!hSCManager)
  852. return FALSE;
  853. hService =
  854. OpenService(
  855. hSCManager,
  856. szService,
  857. SERVICE_QUERY_CONFIG);
  858. if (hService)
  859. {
  860. if (QueryServiceConfig(
  861. hService,
  862. pConfig,
  863. sizeof(szBuffer),
  864. &dwNeeded))
  865. {
  866. strFileName = pConfig->lpBinaryPathName;
  867. // Now fix up the path so that it has a drive letter.
  868. strFileName.MakeUpper();
  869. // If the filename is using \SYSTEMROOT\, replace it with %SystemRoot%.
  870. if (strFileName.Find(_T("\\SYSTEMROOT\\")) == 0)
  871. ReplaceString(strFileName, _T("\\SYSTEMROOT\\"), _T("%SystemRoot%\\"));
  872. // If the filename doesn't start with a replacement string, and if it
  873. // doesn't have a drive letter, assume it should start with
  874. // %SystemRoot%.
  875. else if (strFileName.GetLength() >= 2 &&
  876. strFileName[0] != '%' && strFileName[1] != ':')
  877. {
  878. CHString strTemp;
  879. strTemp.Format(_T("%%SystemRoot%%\\%s"), (LPCTSTR) strFileName);
  880. strFileName = strTemp;
  881. }
  882. TCHAR szOut[MAX_PATH * 2];
  883. ExpandEnvironmentStrings(strFileName, szOut, sizeof(szOut) / sizeof(TCHAR));
  884. strFileName = szOut;
  885. bRet = TRUE;
  886. }
  887. }
  888. return bRet;
  889. }
  890. #endif
  891. ///////////////////////////////////////////////////////////////////
  892. // Performs a case insensitive compare (such as is required for keys)
  893. // on two variants and returns true if they are the same type and
  894. // the same value, else false. Note that arrays, VT_NULL, and
  895. // embedded objects will assert, and return false.
  896. ///////////////////////////////////////////////////////////////////
  897. bool WINAPI CompareVariantsNoCase(const VARIANT *v1, const VARIANT *v2)
  898. {
  899. if (v1->vt == v2->vt)
  900. {
  901. switch (v1->vt)
  902. {
  903. case VT_BOOL: return (v1->boolVal == v2->boolVal);
  904. case VT_UI1: return (v1->bVal == v2->bVal);
  905. case VT_I2: return (v1->iVal == v2->iVal);
  906. case VT_I4: return (v1->lVal == v2->lVal);
  907. case VT_R4: return (v1->fltVal == v2->fltVal);
  908. case VT_R8: return (v1->dblVal == v2->dblVal);
  909. case VT_BSTR: return (0 == _wcsicmp(v1->bstrVal, v2->bstrVal));
  910. default:
  911. ASSERT_BREAK(UNRECOGNIZED_VARIANT_TYPE);
  912. }
  913. }
  914. return false;
  915. }
  916. // map standard API return values (defined WinError.h)
  917. // to WBEMish hresults (defined in WbemCli.h)
  918. HRESULT WINAPI WinErrorToWBEMhResult(LONG error)
  919. {
  920. HRESULT hr = WBEM_E_FAILED;
  921. switch (error)
  922. {
  923. case ERROR_SUCCESS:
  924. hr = WBEM_S_NO_ERROR;
  925. break;
  926. case ERROR_ACCESS_DENIED:
  927. hr = WBEM_E_ACCESS_DENIED;
  928. break;
  929. case ERROR_NOT_ENOUGH_MEMORY:
  930. case ERROR_OUTOFMEMORY:
  931. hr = WBEM_E_OUT_OF_MEMORY;
  932. break;
  933. case ERROR_ALREADY_EXISTS:
  934. hr = WBEM_E_ALREADY_EXISTS;
  935. break;
  936. case ERROR_BAD_NETPATH:
  937. case ERROR_INVALID_DATA:
  938. case ERROR_BAD_PATHNAME:
  939. case REGDB_E_INVALIDVALUE:
  940. case ERROR_PATH_NOT_FOUND:
  941. case ERROR_FILE_NOT_FOUND:
  942. case ERROR_INVALID_PRINTER_NAME:
  943. case ERROR_BAD_USERNAME:
  944. case NERR_NetNameNotFound:
  945. case ERROR_NOT_READY:
  946. case ERROR_INVALID_NAME:
  947. hr = WBEM_E_NOT_FOUND;
  948. break;
  949. default:
  950. hr = WBEM_E_FAILED;
  951. }
  952. return hr;
  953. }
  954. void WINAPI SetConfigMgrProperties(CConfigMgrDevice *pDevice, CInstance *pInstance)
  955. {
  956. CHString strDeviceID;
  957. DWORD dwStatus,
  958. dwProblem;
  959. if (pDevice->GetDeviceID(strDeviceID))
  960. pInstance->SetCHString(IDS_PNPDeviceID, strDeviceID);
  961. if (pDevice->GetStatus(&dwStatus, &dwProblem))
  962. pInstance->SetDWORD(IDS_ConfigManagerErrorCode, dwProblem);
  963. pInstance->SetDWORD(IDS_ConfigManagerUserConfig,
  964. pDevice->IsUsingForcedConfig());
  965. }
  966. #ifdef NTONLY
  967. BOOL WINAPI EnablePrivilegeOnCurrentThread(LPCTSTR szPriv)
  968. {
  969. BOOL bRet = FALSE;
  970. HANDLE hToken = NULL;
  971. TOKEN_PRIVILEGES tkp;
  972. BOOL bLookup = FALSE;
  973. DWORD dwLastError = ERROR_SUCCESS;
  974. // Try to open the thread token.
  975. if (OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES |
  976. TOKEN_QUERY, FALSE, &hToken))
  977. {
  978. {
  979. bLookup = LookupPrivilegeValue(NULL, szPriv, &tkp.Privileges[0].Luid);
  980. }
  981. if (bLookup)
  982. {
  983. tkp.PrivilegeCount = 1;
  984. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  985. // Clear the last error.
  986. SetLastError(0);
  987. // Turn it on
  988. bRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
  989. (PTOKEN_PRIVILEGES) NULL, 0);
  990. dwLastError = GetLastError();
  991. }
  992. CloseHandle(hToken);
  993. }
  994. else
  995. {
  996. dwLastError = ::GetLastError();
  997. }
  998. // We have to check GetLastError() because AdjustTokenPrivileges lies about
  999. // its success but GetLastError() doesn't.
  1000. return bRet && dwLastError == ERROR_SUCCESS;
  1001. }
  1002. #endif
  1003. // Takes a pnp id and returns a bios unit number
  1004. // To avoid frequent load/unload of a library, the pGetWin9XBiosUnit parameter comes from:
  1005. // HINSTANCE hInst = LoadLibrary("cim32net.dll");
  1006. // pGetWin9XBiosUnit = (fnGetWin9XBiosUnit)GetProcAddress(hInst, "GetWin9XBiosUnit");
  1007. #ifdef WIN9XONLY
  1008. BYTE WINAPI GetBiosUnitNumberFromPNPID(CHString strDeviceID)
  1009. {
  1010. CHString sTemp;
  1011. DRIVE_MAP_INFO stDMI;
  1012. CRegistry Reg1;
  1013. BYTE btBiosUnit = -1;
  1014. // Open the associated registry key
  1015. if (Reg1.Open(HKEY_LOCAL_MACHINE, _T("enum\\") + strDeviceID, KEY_QUERY_VALUE) == ERROR_SUCCESS)
  1016. {
  1017. // Get a drive letter for this pnp id
  1018. if ((Reg1.GetCurrentKeyValue(L"CurrentDriveLetterAssignment", sTemp) != ERROR_SUCCESS) ||
  1019. (sTemp.GetLength() == 0)) {
  1020. // No drive letters, let's try one more thing. On memphis sp1, this call will also
  1021. // get us a unit number.
  1022. CCim32NetApi* t_pCim32Net = HoldSingleCim32NetPtr::GetCim32NetApiPtr();
  1023. if (t_pCim32Net != NULL)
  1024. {
  1025. #ifndef UNICODE // This function only takes a LPSTR, and only works on 9x anyway.
  1026. btBiosUnit = t_pCim32Net->GetWin9XBiosUnit(TOBSTRT(strDeviceID));
  1027. CResourceManager::sm_TheResourceManager.ReleaseResource(g_guidCim32NetApi, t_pCim32Net);
  1028. t_pCim32Net = NULL;
  1029. #endif
  1030. }
  1031. }
  1032. else
  1033. {
  1034. if (GetDriveMapInfo(&stDMI, toupper(sTemp[0]) - 'A' + 1))
  1035. {
  1036. btBiosUnit = stDMI.btInt13Unit;
  1037. }
  1038. }
  1039. }
  1040. return btBiosUnit;
  1041. }
  1042. #endif
  1043. HRESULT WINAPI GetHKUserNames(CHStringList &list)
  1044. {
  1045. HRESULT hres;
  1046. // Empty the list.
  1047. list.clear();
  1048. #ifdef NTONLY
  1049. {
  1050. // Enum the profiles from the registry.
  1051. CRegistry regProfileList;
  1052. CHString strProfile;
  1053. DWORD dwErr;
  1054. // Open the ProfileList key so we know which profiles to load up.
  1055. if ((dwErr = regProfileList.OpenAndEnumerateSubKeys(
  1056. HKEY_LOCAL_MACHINE,
  1057. IDS_RegNTProfileList,
  1058. KEY_READ)) == ERROR_SUCCESS)
  1059. {
  1060. for (int i = 0; regProfileList.GetCurrentSubKeyName(strProfile) ==
  1061. ERROR_SUCCESS; i++)
  1062. {
  1063. list.push_back(strProfile);
  1064. regProfileList.NextSubKey();
  1065. }
  1066. }
  1067. // Add the .DEFAULT name.
  1068. list.push_back(_T(".DEFAULT"));
  1069. hres = WinErrorToWBEMhResult(dwErr);
  1070. }
  1071. #endif
  1072. #ifdef WIN9XONLY
  1073. {
  1074. DWORD dwErr = ERROR_SUCCESS;
  1075. #ifdef _DEBUG
  1076. DWORD dwSize = 10,
  1077. #else
  1078. DWORD dwSize = 1024,
  1079. #endif
  1080. dwBytesRead;
  1081. TCHAR *szBuff = NULL;
  1082. // Keep looping until we read the entire section.
  1083. // You know your buffer wasn't big enough if the returned number
  1084. // of bytes == (size passed in - 2).
  1085. do
  1086. {
  1087. if (szBuff)
  1088. {
  1089. delete [] szBuff;
  1090. dwSize *= 2;
  1091. }
  1092. szBuff = new TCHAR [dwSize];
  1093. // Out of memory. Get out of loop.
  1094. if (!szBuff)
  1095. {
  1096. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1097. }
  1098. try
  1099. {
  1100. dwBytesRead =
  1101. GetPrivateProfileString(
  1102. _T("Password Lists"),
  1103. NULL,
  1104. _T(""),
  1105. szBuff,
  1106. dwSize / sizeof(TCHAR),
  1107. _T("system.ini"));
  1108. }
  1109. catch ( ... )
  1110. {
  1111. delete [] szBuff;
  1112. throw;
  1113. }
  1114. } while (dwBytesRead >= dwSize - 2);
  1115. if (szBuff)
  1116. {
  1117. try
  1118. {
  1119. // Loop through the list of names. Each is null-terminated, and the
  1120. // list is terminated with a double null.
  1121. TCHAR *pszCurrent = szBuff;
  1122. while (*pszCurrent)
  1123. {
  1124. list.push_back(pszCurrent);
  1125. pszCurrent += lstrlen(pszCurrent) + 1;
  1126. }
  1127. hres = WBEM_S_NO_ERROR;
  1128. }
  1129. catch ( ... )
  1130. {
  1131. delete [] szBuff;
  1132. throw;
  1133. }
  1134. // Free the buffer.
  1135. delete [] szBuff;
  1136. // Add the .DEFAULT name.
  1137. list.push_back(_T(".DEFAULT"));
  1138. }
  1139. else
  1140. // Failed to malloc, so set error code.
  1141. hres = WBEM_E_OUT_OF_MEMORY;
  1142. }
  1143. #endif
  1144. return hres;
  1145. }
  1146. VOID WINAPI EscapeBackslashes(CHString& chstrIn,
  1147. CHString& chstrOut)
  1148. {
  1149. CHString chstrCpyNormPathname = chstrIn;
  1150. LONG lNext = -1L;
  1151. chstrOut.Empty();
  1152. // Find the next '\'
  1153. lNext = chstrCpyNormPathname.Find(_T('\\'));
  1154. while(lNext != -1)
  1155. {
  1156. // Add on to the new string we are building:
  1157. chstrOut += chstrCpyNormPathname.Left(lNext + 1);
  1158. // Add on the second backslash:
  1159. chstrOut += _T('\\');
  1160. // Hack off from the input string the portion we just copied
  1161. chstrCpyNormPathname = chstrCpyNormPathname.Right(chstrCpyNormPathname.GetLength() - lNext - 1);
  1162. lNext = chstrCpyNormPathname.Find(_T('\\'));
  1163. }
  1164. // If the last character wasn't a '\', there may still be leftovers, so
  1165. // copy them here.
  1166. if(chstrCpyNormPathname.GetLength() != 0)
  1167. {
  1168. chstrOut += chstrCpyNormPathname;
  1169. }
  1170. }
  1171. VOID WINAPI EscapeQuotes(CHString& chstrIn,
  1172. CHString& chstrOut)
  1173. {
  1174. CHString chstrCpyNormPathname = chstrIn;
  1175. LONG lNext = -1L;
  1176. chstrOut.Empty();
  1177. // Find the next '\'
  1178. lNext = chstrCpyNormPathname.Find(_T('\"'));
  1179. while(lNext != -1)
  1180. {
  1181. // Add on to the new string we are building:
  1182. chstrOut += chstrCpyNormPathname.Left(lNext);
  1183. // Escape the quote:
  1184. chstrOut += _T("\\\"");
  1185. // Hack off from the input string the portion we just copied
  1186. chstrCpyNormPathname = chstrCpyNormPathname.Right(chstrCpyNormPathname.GetLength() - lNext - 1);
  1187. lNext = chstrCpyNormPathname.Find(_T('\"'));
  1188. }
  1189. // If the last character wasn't a '\', there may still be leftovers, so
  1190. // copy them here.
  1191. if(chstrCpyNormPathname.GetLength() != 0)
  1192. {
  1193. chstrOut += chstrCpyNormPathname;
  1194. }
  1195. }
  1196. VOID WINAPI RemoveDoubleBackslashes(const CHString& chstrIn, CHString& chstrOut)
  1197. {
  1198. CHString chstrBuildString;
  1199. CHString chstrInCopy = chstrIn;
  1200. BOOL fDone = FALSE;
  1201. LONG lPos = -1;
  1202. while(!fDone)
  1203. {
  1204. lPos = chstrInCopy.Find(L"\\\\");
  1205. if(lPos != -1)
  1206. {
  1207. chstrBuildString += chstrInCopy.Left(lPos);
  1208. chstrBuildString += _T("\\");
  1209. chstrInCopy = chstrInCopy.Mid(lPos+2);
  1210. }
  1211. else
  1212. {
  1213. chstrBuildString += chstrInCopy;
  1214. fDone = TRUE;
  1215. }
  1216. }
  1217. chstrOut = chstrBuildString;
  1218. }
  1219. CHString WINAPI RemoveDoubleBackslashes(const CHString& chstrIn)
  1220. {
  1221. CHString chstrBuildString;
  1222. CHString chstrInCopy = chstrIn;
  1223. BOOL fDone = FALSE;
  1224. LONG lPos = -1;
  1225. while(!fDone)
  1226. {
  1227. lPos = chstrInCopy.Find(L"\\\\");
  1228. if(lPos != -1)
  1229. {
  1230. chstrBuildString += chstrInCopy.Left(lPos);
  1231. chstrBuildString += _T("\\");
  1232. chstrInCopy = chstrInCopy.Mid(lPos+2);
  1233. }
  1234. else
  1235. {
  1236. chstrBuildString += chstrInCopy;
  1237. fDone = TRUE;
  1238. }
  1239. }
  1240. return chstrBuildString;
  1241. }
  1242. #ifdef NTONLY
  1243. // helper for StrToSID
  1244. // takes a string, converts to a SID_IDENTIFIER_AUTHORITY
  1245. // returns false if not a valid SID_IDENTIFIER_AUTHORITY
  1246. // contents of identifierAuthority are unrelieable on failure
  1247. bool WINAPI StrToIdentifierAuthority(const CHString& str, SID_IDENTIFIER_AUTHORITY& identifierAuthority)
  1248. {
  1249. bool bRet = false;
  1250. memset(&identifierAuthority, '\0', sizeof(SID_IDENTIFIER_AUTHORITY));
  1251. DWORD duhWord;
  1252. WCHAR* p = NULL;
  1253. CHString localStr(str);
  1254. // per KB article Q13132, if identifier authority is greater than 2**32, it's in hex
  1255. if ((localStr[0] == '0') && ((localStr[1] == 'x') || (localStr[1] == 'X')))
  1256. // if it looks hexidecimalish...
  1257. {
  1258. // going to parse this out backwards, chpping two chars off the end at a time
  1259. // first, whack off the 0x
  1260. localStr = localStr.Mid(2);
  1261. CHString token;
  1262. int nValue =5;
  1263. bRet = true;
  1264. while (bRet && localStr.GetLength() && (nValue > 0))
  1265. {
  1266. token = localStr.Right(2);
  1267. localStr = localStr.Left(localStr.GetLength() -2);
  1268. duhWord = wcstoul(token, &p, 16);
  1269. // if strtoul succeeds, the pointer is moved
  1270. if (p != (LPCTSTR)token)
  1271. identifierAuthority.Value[nValue--] = (BYTE)duhWord;
  1272. else
  1273. bRet = false;
  1274. }
  1275. }
  1276. else
  1277. // it looks decimalish
  1278. {
  1279. duhWord = wcstoul(localStr, &p, 10);
  1280. if (p != (LPCTSTR)localStr)
  1281. // conversion succeeded
  1282. {
  1283. bRet = true;
  1284. identifierAuthority.Value[5] = LOBYTE(LOWORD(duhWord));
  1285. identifierAuthority.Value[4] = HIBYTE(LOWORD(duhWord));
  1286. identifierAuthority.Value[3] = LOBYTE(HIWORD(duhWord));
  1287. identifierAuthority.Value[2] = HIBYTE(HIWORD(duhWord));
  1288. }
  1289. }
  1290. return bRet;
  1291. }
  1292. // for input of the form AAA-BBB-CCC
  1293. // will return AAA in token
  1294. // and BBB-CCC in str
  1295. bool WINAPI WhackToken(CHString& str, CHString& token)
  1296. {
  1297. bool bRet = false;
  1298. if (bRet = !str.IsEmpty())
  1299. {
  1300. int index;
  1301. index = str.Find('-');
  1302. if (index == -1)
  1303. {
  1304. // all that's left is the token, we're done
  1305. token = str;
  1306. str.Empty();
  1307. }
  1308. else
  1309. {
  1310. token = str.Left(index);
  1311. str = str.Mid(index+1);
  1312. }
  1313. }
  1314. return bRet;
  1315. }
  1316. // a string representation of a SID is assumed to be:
  1317. // S-#-####-####-####-####-####-####
  1318. // we will enforce only the S ourselves,
  1319. // The version is not checked
  1320. // everything else will be handed off to the OS
  1321. // caller must free the SID returned
  1322. PSID WINAPI StrToSID(const CHString& sid)
  1323. {
  1324. PSID pSid = NULL;
  1325. if (!sid.IsEmpty() && ((sid[0] == 'S')||(sid[0] == 's')) && (sid[1] == '-'))
  1326. {
  1327. // get a local copy we can play with
  1328. // we'll parse this puppy the easy way
  1329. // by slicing off each token as we find it
  1330. // slow but sure
  1331. // start by slicing off the "S-"
  1332. CHString str(sid.Mid(2));
  1333. CHString token;
  1334. SID_IDENTIFIER_AUTHORITY identifierAuthority = {0,0,0,0,0,0};
  1335. BYTE nSubAuthorityCount =0; // count of subauthorities
  1336. DWORD dwSubAuthority[8] = {0,0,0,0,0,0,0,0}; // subauthorities
  1337. // skip version
  1338. WhackToken(str, token);
  1339. // Grab Authority
  1340. if (WhackToken(str, token))
  1341. {
  1342. DWORD duhWord;
  1343. WCHAR* p = NULL;
  1344. bool bDoIt = false;
  1345. if (StrToIdentifierAuthority(token, identifierAuthority))
  1346. // conversion succeeded
  1347. {
  1348. bDoIt = true;
  1349. // now fill up the subauthorities
  1350. while (bDoIt && WhackToken(str, token))
  1351. {
  1352. p = NULL;
  1353. duhWord = wcstoul(token, &p, 10);
  1354. if (p != (LPCTSTR)token)
  1355. {
  1356. dwSubAuthority[nSubAuthorityCount] = duhWord;
  1357. bDoIt = (++nSubAuthorityCount <= 8);
  1358. }
  1359. else
  1360. bDoIt = false;
  1361. } // end while WhackToken
  1362. if(bDoIt)
  1363. {
  1364. AllocateAndInitializeSid(&identifierAuthority,
  1365. nSubAuthorityCount,
  1366. dwSubAuthority[0],
  1367. dwSubAuthority[1],
  1368. dwSubAuthority[2],
  1369. dwSubAuthority[3],
  1370. dwSubAuthority[4],
  1371. dwSubAuthority[5],
  1372. dwSubAuthority[6],
  1373. dwSubAuthority[7],
  1374. &pSid);
  1375. }
  1376. }
  1377. }
  1378. }
  1379. return pSid;
  1380. }
  1381. #endif // NTONLY defined
  1382. CHString WINAPI GetDateTimeViaFilenameFiletime(LPCTSTR szFilename, FILETIME *pFileTime)
  1383. {
  1384. CHString strDate,
  1385. strRootPath;
  1386. // UNC path?
  1387. if (szFilename[0] == '\\' && szFilename[1] == '\\')
  1388. {
  1389. LPTSTR szSlash = _tcschr(&szFilename[2], '\\');
  1390. // If szSlash, we're sitting on 3rd slash of \\server\share\myfile
  1391. if (szSlash)
  1392. {
  1393. szSlash = _tcschr(szSlash + 1, '\\');
  1394. // If no 4th slash, there's no filename.
  1395. if (szSlash)
  1396. {
  1397. strRootPath = szFilename;
  1398. strRootPath =
  1399. strRootPath.Left(szSlash - szFilename + 1);
  1400. }
  1401. }
  1402. }
  1403. // Drive path?
  1404. else if (szFilename[1] == ':')
  1405. {
  1406. strRootPath = szFilename;
  1407. strRootPath = strRootPath.Left(3);
  1408. }
  1409. if (!strRootPath.IsEmpty())
  1410. {
  1411. TCHAR szBuffer[MAX_PATH];
  1412. BOOL bNTFS = FALSE;
  1413. if (GetVolumeInformation(
  1414. TOBSTRT(strRootPath),
  1415. NULL,
  1416. 0,
  1417. NULL,
  1418. NULL,
  1419. NULL,
  1420. szBuffer,
  1421. sizeof(szBuffer) / sizeof(TCHAR)) &&
  1422. !lstrcmpi(szBuffer, _T("NTFS")))
  1423. {
  1424. bNTFS = TRUE;
  1425. }
  1426. strDate = GetDateTimeViaFilenameFiletime(bNTFS, pFileTime);
  1427. }
  1428. return strDate;
  1429. }
  1430. CHString WINAPI GetDateTimeViaFilenameFiletime(LPCTSTR szFilename, FT_ENUM ftWhich)
  1431. {
  1432. WIN32_FIND_DATA finddata;
  1433. SmartFindClose hFind = FindFirstFile(szFilename, &finddata);
  1434. CHString strDate;
  1435. if (hFind != INVALID_HANDLE_VALUE)
  1436. {
  1437. FILETIME *pFileTime = NULL;
  1438. switch(ftWhich)
  1439. {
  1440. case FT_CREATION_DATE:
  1441. pFileTime = &finddata.ftCreationTime;
  1442. break;
  1443. case FT_ACCESSED_DATE:
  1444. pFileTime = &finddata.ftLastAccessTime;
  1445. break;
  1446. case FT_MODIFIED_DATE:
  1447. pFileTime = &finddata.ftLastWriteTime;
  1448. break;
  1449. default:
  1450. // Caller must send in a proper enum value.
  1451. ASSERT_BREAK(FALSE);
  1452. break;
  1453. }
  1454. if (pFileTime)
  1455. strDate = GetDateTimeViaFilenameFiletime(szFilename, pFileTime);
  1456. }
  1457. return strDate;
  1458. }
  1459. CHString WINAPI GetDateTimeViaFilenameFiletime(BOOL bNTFS, FILETIME *pFileTime)
  1460. {
  1461. WBEMTime wbemTime(*pFileTime);
  1462. // This is just used as a wrapper. It avoids a try/catch block.
  1463. bstr_t bstrDate(bNTFS ? wbemTime.GetDMTF() : wbemTime.GetDMTFNonNtfs(), false);
  1464. CHString strRet = (LPWSTR) bstrDate;
  1465. return strRet;
  1466. }
  1467. // Used to validate a numbered device ID is OK.
  1468. // Example: ValidateNumberedDeviceID("VideoController7", "VideoController", pdwWhich)
  1469. // returns TRUE, pdwWhich = 7.
  1470. // Example: ValidateNumberedDeviceID("BadDeviceID", "VideoController", pdwWhich)
  1471. // returns FALSE, pdwWhich unchanged
  1472. BOOL WINAPI ValidateNumberedDeviceID(LPCWSTR szDeviceID, LPCWSTR szTag, DWORD *pdwWhich)
  1473. {
  1474. BOOL bRet = FALSE;
  1475. int nTagLen = wcslen(szTag);
  1476. if (wcslen(szDeviceID) > nTagLen)
  1477. {
  1478. CHString strDeviceID;
  1479. DWORD dwWhich = _wtoi(&szDeviceID[nTagLen]);
  1480. strDeviceID.Format(L"%s%d", szTag, dwWhich);
  1481. if (!_wcsicmp(szDeviceID, strDeviceID))
  1482. {
  1483. bRet = TRUE;
  1484. *pdwWhich = dwWhich;
  1485. }
  1486. }
  1487. return bRet;
  1488. }
  1489. // Critical sections used by various
  1490. CCritSec g_csPrinter;
  1491. CCritSec g_csSystemName;
  1492. #ifdef WIN9XONLY
  1493. CCritSec g_csVXD;
  1494. #endif
  1495. #define STR_BLK_SIZE 256
  1496. #define CHAR_FUDGE 1 // one WCHAR unused is good enough
  1497. BOOL LoadStringW(CHString &sString, UINT nID)
  1498. {
  1499. // try fixed buffer first (to avoid wasting space in the heap)
  1500. WCHAR szTemp[ STR_BLK_SIZE ];
  1501. int nLen = LoadStringW(nID, szTemp, STR_BLK_SIZE);
  1502. if (STR_BLK_SIZE - nLen > CHAR_FUDGE)
  1503. {
  1504. sString = szTemp;
  1505. }
  1506. else
  1507. {
  1508. // try buffer size of 512, then larger size until entire string is retrieved
  1509. int nSize = STR_BLK_SIZE;
  1510. do
  1511. {
  1512. nSize += STR_BLK_SIZE;
  1513. nLen = LoadStringW(nID, sString.GetBuffer(nSize-1), nSize);
  1514. }
  1515. while (nSize - nLen <= CHAR_FUDGE);
  1516. sString.ReleaseBuffer();
  1517. }
  1518. return nLen > 0;
  1519. }
  1520. void Format(CHString &sString, UINT nFormatID, ...)
  1521. {
  1522. va_list argList;
  1523. va_start(argList, nFormatID);
  1524. CHString strFormat;
  1525. LoadStringW(strFormat, nFormatID);
  1526. sString.FormatV(strFormat, argList);
  1527. va_end(argList);
  1528. }
  1529. void FormatMessageW(CHString &sString, UINT nFormatID, ...)
  1530. {
  1531. // get format string from string table
  1532. CHString strFormat;
  1533. LoadStringW(strFormat, nFormatID);
  1534. // format message into temporary buffer lpszTemp
  1535. va_list argList;
  1536. va_start(argList, nFormatID);
  1537. #ifdef NTONLY
  1538. LPWSTR lpszTemp;
  1539. if (::FormatMessageW(
  1540. FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  1541. (LPCWSTR) strFormat,
  1542. 0,
  1543. 0,
  1544. (LPWSTR) &lpszTemp,
  1545. 0,
  1546. &argList) == 0 || lpszTemp == NULL)
  1547. {
  1548. // Should throw memory exception here. Now we do.
  1549. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  1550. }
  1551. else
  1552. {
  1553. // assign lpszTemp into the resulting string and free lpszTemp
  1554. sString = lpszTemp;
  1555. LocalFree(lpszTemp);
  1556. va_end(argList);
  1557. }
  1558. #else
  1559. #error Not written for win9x
  1560. #endif
  1561. }
  1562. int LoadStringW(UINT nID, LPWSTR lpszBuf, UINT nMaxBuf)
  1563. {
  1564. int nLen = 0;
  1565. #ifdef NTONLY
  1566. nLen = ::LoadStringW(ghModule, nID, lpszBuf, nMaxBuf);
  1567. if (nLen == 0)
  1568. {
  1569. lpszBuf[0] = '\0';
  1570. }
  1571. #else
  1572. #error Not written for win9x
  1573. #endif
  1574. return nLen; // excluding terminator
  1575. }
  1576. bool WINAPI DelayLoadDllExceptionFilter(PEXCEPTION_POINTERS pep)
  1577. {
  1578. // We might have thrown as a result of the
  1579. // delay load library mechanism. There are
  1580. // two types of such exceptions - those
  1581. // generated because the dll could not be
  1582. // loaded, and thos generated because the
  1583. // proc address of the function referred to
  1584. // could not be found. We want to log an
  1585. // error message in either case.
  1586. bool fRet = false;
  1587. if(pep &&
  1588. pep->ExceptionRecord)
  1589. {
  1590. // If this is a Delay-load problem, ExceptionInformation[0] points
  1591. // to a DelayLoadInfo structure that has detailed error info
  1592. PDelayLoadInfo pdli = PDelayLoadInfo(
  1593. pep->ExceptionRecord->ExceptionInformation[0]);
  1594. if(pdli)
  1595. {
  1596. switch(pep->ExceptionRecord->ExceptionCode)
  1597. {
  1598. case VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND):
  1599. {
  1600. // The DLL module was not found at runtime
  1601. LogErrorMessage2(L"Dll not found: %s", pdli->szDll);
  1602. fRet = true;
  1603. break;
  1604. }
  1605. case VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND):
  1606. {
  1607. // The DLL module was found but it doesn't contain the function
  1608. if(pdli->dlp.fImportByName)
  1609. {
  1610. LogErrorMessage3(
  1611. L"Function %s was not found in %s",
  1612. pdli->dlp.szProcName,
  1613. pdli->szDll);
  1614. }
  1615. else
  1616. {
  1617. LogErrorMessage3(
  1618. L"Function ordinal %d was not found in %s",
  1619. pdli->dlp.dwOrdinal,
  1620. pdli->szDll);
  1621. }
  1622. fRet = true;
  1623. break;
  1624. }
  1625. }
  1626. }
  1627. }
  1628. return fRet;
  1629. }
  1630. // This is here in common because
  1631. // at least the classes Pagefile and
  1632. // PageFileSetting use it, perhaps
  1633. // more in the future.
  1634. #ifdef NTONLY
  1635. HRESULT CreatePageFile(
  1636. LPCWSTR wstrPageFileName,
  1637. const LARGE_INTEGER liInitial,
  1638. const LARGE_INTEGER liMaximum,
  1639. const CInstance& Instance)
  1640. {
  1641. HRESULT hr = WBEM_S_NO_ERROR;
  1642. UNICODE_STRING ustrFileName = { 0 };
  1643. NTSTATUS status = STATUS_SUCCESS;
  1644. if(!EnablePrivilegeOnCurrentThread(SE_CREATE_PAGEFILE_NAME))
  1645. {
  1646. SetSinglePrivilegeStatusObject(
  1647. Instance.GetMethodContext(),
  1648. SE_CREATE_PAGEFILE_NAME);
  1649. hr = WBEM_E_ACCESS_DENIED;
  1650. }
  1651. if(SUCCEEDED(hr))
  1652. {
  1653. if(!::RtlDosPathNameToNtPathName_U(
  1654. wstrPageFileName,
  1655. &ustrFileName,
  1656. NULL,
  1657. NULL) && ustrFileName.Buffer)
  1658. {
  1659. hr = WBEM_E_INVALID_PARAMETER;
  1660. }
  1661. }
  1662. try
  1663. {
  1664. if(SUCCEEDED(hr))
  1665. {
  1666. LARGE_INTEGER liInit;
  1667. LARGE_INTEGER liMax;
  1668. liInit.QuadPart = liInitial.QuadPart * 1024 * 1024;
  1669. liMax.QuadPart = liMaximum.QuadPart * 1024 * 1024;
  1670. if(!NT_SUCCESS(
  1671. status = ::NtCreatePagingFile(
  1672. &ustrFileName,
  1673. &liInit,
  1674. &liMax,
  1675. 0)))
  1676. {
  1677. if (STATUS_INVALID_PARAMETER_2 == status)
  1678. hr = WBEM_E_VALUE_OUT_OF_RANGE;
  1679. else
  1680. hr = WinErrorToWBEMhResult(RtlNtStatusToDosError(status));
  1681. }
  1682. }
  1683. RtlFreeUnicodeString(&ustrFileName);
  1684. ustrFileName.Buffer = NULL;
  1685. }
  1686. catch(...)
  1687. {
  1688. RtlFreeUnicodeString(&ustrFileName);
  1689. ustrFileName.Buffer = NULL;
  1690. throw;
  1691. }
  1692. return hr;
  1693. }
  1694. #endif
  1695. // Useful for obtaining the localized versions
  1696. // of "All Users" and "Default User".
  1697. #if NTONLY >= 5
  1698. bool GetAllUsersName(CHString& chstrAllUsersName)
  1699. {
  1700. bool fRet = false;
  1701. CRegistry reg;
  1702. CHString chstrTemp;
  1703. DWORD dwRet = reg.Open(
  1704. HKEY_LOCAL_MACHINE,
  1705. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
  1706. KEY_READ);
  1707. if(dwRet == ERROR_SUCCESS)
  1708. {
  1709. if(reg.GetCurrentKeyValue(
  1710. L"AllUsersProfile",
  1711. chstrTemp) == ERROR_SUCCESS)
  1712. {
  1713. chstrAllUsersName = chstrTemp.SpanExcluding(L".");
  1714. fRet = true;
  1715. }
  1716. }
  1717. if(!fRet)
  1718. {
  1719. chstrAllUsersName = L"";
  1720. }
  1721. return fRet;
  1722. }
  1723. #endif
  1724. #if NTONLY >= 5
  1725. bool GetDefaultUsersName(CHString& chstrDefaultUsersName)
  1726. {
  1727. bool fRet = false;
  1728. CRegistry reg;
  1729. CHString chstrTemp;
  1730. DWORD dwRet = reg.Open(
  1731. HKEY_LOCAL_MACHINE,
  1732. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
  1733. KEY_READ);
  1734. if(dwRet == ERROR_SUCCESS)
  1735. {
  1736. if(reg.GetCurrentKeyValue(
  1737. L"DefaultUserProfile",
  1738. chstrTemp) == ERROR_SUCCESS)
  1739. {
  1740. chstrDefaultUsersName = chstrTemp.SpanExcluding(L".");
  1741. fRet = true;
  1742. }
  1743. }
  1744. if(!fRet)
  1745. {
  1746. chstrDefaultUsersName = L"";
  1747. }
  1748. return fRet;
  1749. }
  1750. #endif
  1751. #if NTONLY >= 5
  1752. bool GetCommonStartup(CHString& chstrCommonStartup)
  1753. {
  1754. bool fRet = false;
  1755. CRegistry reg;
  1756. CHString chstrTemp;
  1757. DWORD dwRet = reg.Open(
  1758. HKEY_LOCAL_MACHINE,
  1759. L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
  1760. KEY_READ);
  1761. if(dwRet == ERROR_SUCCESS)
  1762. {
  1763. if(reg.GetCurrentKeyValue(
  1764. L"Common Startup",
  1765. chstrTemp) == ERROR_SUCCESS)
  1766. {
  1767. int iPos = chstrTemp.ReverseFind(L'\\');
  1768. if(iPos != -1)
  1769. {
  1770. chstrCommonStartup = chstrTemp.Mid(iPos+1);
  1771. fRet = true;
  1772. }
  1773. }
  1774. }
  1775. if(!fRet)
  1776. {
  1777. chstrCommonStartup = L"";
  1778. }
  1779. return fRet;
  1780. }
  1781. #endif
  1782. BOOL GetLocalizedNTAuthorityString(
  1783. CHString& chstrNT_AUTHORITY)
  1784. {
  1785. BOOL fRet = false;
  1786. SID_IDENTIFIER_AUTHORITY siaNTSidAuthority = SECURITY_NT_AUTHORITY;
  1787. CSid csidAccountSid;
  1788. if(GetSysAccountNameAndDomain(
  1789. &siaNTSidAuthority,
  1790. csidAccountSid,
  1791. 1,
  1792. SECURITY_NETWORK_SERVICE_RID))
  1793. {
  1794. chstrNT_AUTHORITY = csidAccountSid.GetDomainName();
  1795. fRet = TRUE;
  1796. }
  1797. return fRet;
  1798. }
  1799. BOOL GetLocalizedBuiltInString(
  1800. CHString& chstrBuiltIn)
  1801. {
  1802. BOOL fRet = false;
  1803. SID_IDENTIFIER_AUTHORITY siaNTSidAuthority = SECURITY_NT_AUTHORITY;
  1804. CSid csidAccountSid;
  1805. if(GetSysAccountNameAndDomain(
  1806. &siaNTSidAuthority,
  1807. csidAccountSid,
  1808. 1,
  1809. SECURITY_BUILTIN_DOMAIN_RID))
  1810. {
  1811. chstrBuiltIn = csidAccountSid.GetDomainName();
  1812. fRet = TRUE;
  1813. }
  1814. return fRet;
  1815. }
  1816. BOOL GetSysAccountNameAndDomain(
  1817. PSID_IDENTIFIER_AUTHORITY a_pAuthority,
  1818. CSid& a_accountsid,
  1819. BYTE a_saCount /*=0*/,
  1820. DWORD a_dwSubAuthority1 /*=0*/,
  1821. DWORD a_dwSubAuthority2 /*=0*/ )
  1822. {
  1823. BOOL t_fReturn = FALSE;
  1824. PSID t_psid = NULL;
  1825. if ( AllocateAndInitializeSid( a_pAuthority,
  1826. a_saCount,
  1827. a_dwSubAuthority1,
  1828. a_dwSubAuthority2,
  1829. 0,
  1830. 0,
  1831. 0,
  1832. 0,
  1833. 0,
  1834. 0,
  1835. &t_psid ) )
  1836. {
  1837. try
  1838. {
  1839. CSid t_sid( t_psid ) ;
  1840. // The SID may be valid in this case, however the Lookup may have failed
  1841. if ( t_sid.IsValid() && t_sid.IsOK() )
  1842. {
  1843. a_accountsid = t_sid;
  1844. t_fReturn = TRUE;
  1845. }
  1846. }
  1847. catch( ... )
  1848. {
  1849. if( t_psid )
  1850. {
  1851. FreeSid( t_psid ) ;
  1852. }
  1853. throw ;
  1854. }
  1855. // Cleanup the sid
  1856. FreeSid( t_psid ) ;
  1857. }
  1858. return t_fReturn;
  1859. }