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.

834 lines
22 KiB

  1. #include "precomp.h"
  2. #include <tchar.h>
  3. #include <malloc.h>
  4. #include <mofcomp.h> // for AUTORECOVERY_REQUIRED
  5. #include "winmgmt.h" // this project
  6. #include "arrtempl.h" // for CDeleteMe
  7. //
  8. //
  9. // CheckNoResyncSwitch
  10. //
  11. //////////////////////////////////////////////////////////////////
  12. BOOL CheckNoResyncSwitch( void )
  13. {
  14. BOOL bRetVal = TRUE;
  15. DWORD dwVal = 0;
  16. Registry rCIMOM(WBEM_REG_WINMGMT);
  17. if (rCIMOM.GetDWORDStr( WBEM_NORESYNCPERF, &dwVal ) == Registry::no_error)
  18. {
  19. bRetVal = !dwVal;
  20. if ( bRetVal )
  21. {
  22. DEBUGTRACE((LOG_WBEMCORE, "NoResyncPerf in CIMOM is set to TRUE - ADAP will not be shelled\n"));
  23. }
  24. }
  25. // If we didn't get anything there, we should try the volatile key
  26. if ( bRetVal )
  27. {
  28. Registry rAdap( HKEY_LOCAL_MACHINE, KEY_READ, WBEM_REG_ADAP);
  29. if ( rAdap.GetDWORD( WBEM_NOSHELL, &dwVal ) == Registry::no_error )
  30. {
  31. bRetVal = !dwVal;
  32. if ( bRetVal )
  33. {
  34. DEBUGTRACE((LOG_WBEMCORE,
  35. "NoShell in ADAP is set to TRUE - ADAP will not be shelled\n"));
  36. }
  37. }
  38. }
  39. return bRetVal;
  40. }
  41. //
  42. //
  43. // CheckNoResyncSwitch
  44. //
  45. //////////////////////////////////////////////////////////////////
  46. BOOL
  47. CheckSetupSwitch( void )
  48. {
  49. BOOL bRetVal = FALSE;
  50. DWORD dwVal = 0;
  51. Registry r(WBEM_REG_WINMGMT);
  52. if (r.GetDWORDStr( WBEM_WMISETUP, &dwVal ) == Registry::no_error)
  53. {
  54. bRetVal = dwVal;
  55. DEBUGTRACE((LOG_WBEMCORE, "Registry entry is indicating a setup is running\n"));
  56. }
  57. return bRetVal;
  58. }
  59. //
  60. //
  61. // CheckGlobalSetupSwitch
  62. //
  63. //////////////////////////////////////////////////////////////////
  64. BOOL
  65. CheckGlobalSetupSwitch( void )
  66. {
  67. BOOL bRetVal = FALSE;
  68. DWORD dwVal = 0;
  69. Registry r(_T("system\\Setup"));
  70. if (r.GetDWORD(_T("SystemSetupInProgress"), &dwVal ) == Registry::no_error)
  71. {
  72. if(dwVal == 1)
  73. bRetVal = TRUE;
  74. }
  75. return bRetVal;
  76. }
  77. //
  78. //
  79. //
  80. // This function will place a volatile registry key under the
  81. // CIMOM key in which we will write a value indicating
  82. // we should not shell ADAP. This way, after a setup runs, WINMGMT
  83. // will NOT automatically shell ADAP dredges of the registry,
  84. // until the system is rebooted and the volatile registry key is removed.
  85. //
  86. //
  87. ///////////////////////////////////////////////////////////////////////////
  88. void SetNoShellADAPSwitch( void )
  89. {
  90. HKEY hKey = NULL;
  91. DWORD dwDisposition = 0;
  92. Registry r( HKEY_LOCAL_MACHINE,
  93. REG_OPTION_VOLATILE, KEY_ALL_ACCESS, WBEM_REG_ADAP );
  94. if ( ERROR_SUCCESS == r.GetLastError() )
  95. {
  96. if ( r.SetDWORD( WBEM_NOSHELL, 1 ) != Registry::no_error )
  97. {
  98. DEBUGTRACE( ( LOG_WINMGMT, "Failed to create NoShell value in volatile reg key: %d\n",
  99. r.GetLastError() ) );
  100. }
  101. RegCloseKey( hKey );
  102. }
  103. else
  104. {
  105. DEBUGTRACE( ( LOG_WINMGMT, "Failed to create volatile ADAP reg key: %d\n", r.GetLastError() ) );
  106. }
  107. }
  108. //
  109. //
  110. // bool IsValidMulti
  111. //
  112. //
  113. // Does a sanity check on a multstring.
  114. //
  115. //////////////////////////////////////////////////////////////////////
  116. BOOL IsValidMulti(TCHAR * pMultStr, DWORD dwSize)
  117. {
  118. // Divide the size by the size of a tchar, in case these
  119. // are WCHAR strings
  120. dwSize /= sizeof(TCHAR);
  121. if(pMultStr && dwSize >= 2 && pMultStr[dwSize-2]==0 && pMultStr[dwSize-1]==0)
  122. return TRUE;
  123. return FALSE;
  124. }
  125. //
  126. //
  127. // BOOL IsStringPresetn
  128. //
  129. //
  130. // Searches a multstring for the presense of a string.
  131. //
  132. //
  133. ////////////////////////////////////////////////////////////////////
  134. BOOL IsStringPresent(TCHAR * pTest, TCHAR * pMultStr)
  135. {
  136. TCHAR * pTemp;
  137. for(pTemp = pMultStr; *pTemp; pTemp += lstrlen(pTemp) + 1)
  138. if(!lstrcmpi(pTest, pTemp))
  139. return TRUE;
  140. return FALSE;
  141. }
  142. //
  143. //
  144. // AddToAutoRecoverList
  145. //
  146. //
  147. ////////////////////////////////////////////////////////////////////
  148. void AddToAutoRecoverList(TCHAR * pFileName)
  149. {
  150. TCHAR cFullFileName[MAX_PATH+1];
  151. TCHAR * lpFile;
  152. DWORD dwSize;
  153. TCHAR * pNew = NULL;
  154. TCHAR * pTest;
  155. DWORD dwNewSize = 0;
  156. // Get the full file name
  157. long lRet = GetFullPathName(pFileName, MAX_PATH, cFullFileName, &lpFile);
  158. if(lRet == 0)
  159. return;
  160. BOOL bFound = FALSE;
  161. Registry r(WBEM_REG_WINMGMT);
  162. TCHAR *pMulti = r.GetMultiStr(__TEXT("Autorecover MOFs"), dwSize);
  163. // Ignore the empty string case
  164. if(dwSize == 1)
  165. {
  166. delete pMulti;
  167. pMulti = NULL;
  168. }
  169. if(pMulti)
  170. {
  171. if(!IsValidMulti(pMulti, dwSize))
  172. {
  173. delete pMulti;
  174. return; // bail out, messed up multistring
  175. }
  176. bFound = IsStringPresent(cFullFileName, pMulti);
  177. if(!bFound)
  178. {
  179. // The registry entry does exist, but doesnt have this name
  180. // Make a new multistring with the file name at the end
  181. dwNewSize = dwSize + ((lstrlen(cFullFileName) + 1) * sizeof(TCHAR));
  182. pNew = new TCHAR[dwNewSize / sizeof(TCHAR)];
  183. if(!pNew)
  184. return;
  185. memcpy(pNew, pMulti, dwSize);
  186. // Find the double null
  187. for(pTest = pNew; pTest[0] || pTest[1]; pTest++); // intentional semi
  188. // Tack on the path and ensure a double null;
  189. pTest++;
  190. lstrcpy(pTest, cFullFileName);
  191. pTest+= lstrlen(cFullFileName)+1;
  192. *pTest = 0; // add second numm
  193. }
  194. }
  195. else
  196. {
  197. // The registry entry just doesnt exist.
  198. // Create it with a value equal to our name
  199. dwNewSize = ((lstrlen(cFullFileName) + 2) * sizeof(TCHAR));
  200. pNew = new TCHAR[dwNewSize / sizeof(TCHAR)];
  201. if(!pNew)
  202. return;
  203. lstrcpy(pNew, cFullFileName);
  204. pTest = pNew + lstrlen(pNew) + 1;
  205. *pTest = 0; // add second null
  206. }
  207. if(pNew)
  208. {
  209. // We will cast pNew, since the underlying function will have to cast to
  210. // LPBYTE and we will be WCHAR if UNICODE is defined
  211. r.SetMultiStr(__TEXT("Autorecover MOFs"), pNew, dwNewSize);
  212. delete pNew;
  213. }
  214. FILETIME ftCurTime;
  215. LARGE_INTEGER liCurTime;
  216. TCHAR szBuff[50];
  217. GetSystemTimeAsFileTime(&ftCurTime);
  218. liCurTime.LowPart = ftCurTime.dwLowDateTime;
  219. liCurTime.HighPart = ftCurTime.dwHighDateTime;
  220. _ui64tot(liCurTime.QuadPart, szBuff, 10);
  221. r.SetStr(__TEXT("Autorecover MOFs timestamp"), szBuff);
  222. }
  223. //
  224. // LoadMofsInDirectory
  225. //
  226. //
  227. ////////////////////////////////////////////////////////////////////////////////////////
  228. void LoadMofsInDirectory(const TCHAR *szDirectory)
  229. {
  230. if (NULL == szDirectory)
  231. return;
  232. if(CheckGlobalSetupSwitch())
  233. return; // not hot compiling during setup!
  234. TCHAR *szHotMofDirFF = new TCHAR[lstrlen(szDirectory) + lstrlen(__TEXT("\\*")) + 1];
  235. if(!szHotMofDirFF)return;
  236. CDeleteMe<TCHAR> delMe1(szHotMofDirFF);
  237. TCHAR *szHotMofDirBAD = new TCHAR[lstrlen(szDirectory) + lstrlen(__TEXT("\\bad\\")) + 1];
  238. if(!szHotMofDirBAD)return;
  239. CDeleteMe<TCHAR> delMe2(szHotMofDirBAD);
  240. TCHAR *szHotMofDirGOOD = new TCHAR[lstrlen(szDirectory) + lstrlen(__TEXT("\\good\\")) + 1];
  241. if(!szHotMofDirGOOD)return;
  242. CDeleteMe<TCHAR> delMe3(szHotMofDirGOOD);
  243. IWinmgmtMofCompiler * pCompiler = NULL;
  244. //Find search parameter
  245. lstrcpy(szHotMofDirFF, szDirectory);
  246. lstrcat(szHotMofDirFF, __TEXT("\\*"));
  247. //Where bad mofs go
  248. lstrcpy(szHotMofDirBAD, szDirectory);
  249. lstrcat(szHotMofDirBAD, __TEXT("\\bad\\"));
  250. //Where good mofs go
  251. lstrcpy(szHotMofDirGOOD, szDirectory);
  252. lstrcat(szHotMofDirGOOD, __TEXT("\\good\\"));
  253. //Make sure directories exist
  254. WbemCreateDirectory(szDirectory);
  255. WbemCreateDirectory(szHotMofDirBAD);
  256. WbemCreateDirectory(szHotMofDirGOOD);
  257. //Find file...
  258. WIN32_FIND_DATA ffd;
  259. HANDLE hFF = FindFirstFile(szHotMofDirFF, &ffd);
  260. if (hFF != INVALID_HANDLE_VALUE)
  261. {
  262. do
  263. {
  264. //We only process if this is a file
  265. if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  266. {
  267. //Create a full filename with path
  268. TCHAR *szFullFilename = new TCHAR[lstrlen(szDirectory) + lstrlen(__TEXT("\\")) + lstrlen(ffd.cFileName) + 1];
  269. if(!szFullFilename) return;
  270. CDeleteMe<TCHAR> delMe4(szFullFilename);
  271. lstrcpy(szFullFilename, szDirectory);
  272. lstrcat(szFullFilename, __TEXT("\\"));
  273. lstrcat(szFullFilename, ffd.cFileName);
  274. TRACE((LOG_WBEMCORE,"Auto-loading MOF %s\n", szFullFilename));
  275. //We need to hold off on this file until it has been finished writing
  276. //otherwise the CompileFile will not be able to read the file!
  277. HANDLE hMof = INVALID_HANDLE_VALUE;
  278. DWORD dwRetry = 10;
  279. while (hMof == INVALID_HANDLE_VALUE)
  280. {
  281. hMof = CreateFile(szFullFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  282. //If cannot open yet sleep for a while
  283. if (hMof == INVALID_HANDLE_VALUE)
  284. {
  285. if (--dwRetry == 0)
  286. break;
  287. Sleep(1000);
  288. }
  289. }
  290. DWORD dwRetCode;
  291. WBEM_COMPILE_STATUS_INFO Info;
  292. DWORD dwAutoRecoverRequired = 0;
  293. if (hMof == INVALID_HANDLE_VALUE)
  294. {
  295. TRACE((LOG_WBEMCORE,"Auto-loading MOF %s failed because we could not open it for exclusive access\n", szFullFilename));
  296. dwRetCode = 1;
  297. }
  298. else
  299. {
  300. CloseHandle(hMof);
  301. //Load the MOF file
  302. if(szFullFilename)
  303. {
  304. if (pCompiler == 0)
  305. {
  306. SCODE sc = CoCreateInstance(CLSID_WinmgmtMofCompiler,
  307. 0,
  308. CLSCTX_INPROC_SERVER,
  309. IID_IWinmgmtMofCompiler,
  310. (LPVOID *) &pCompiler);
  311. if(sc != S_OK)
  312. return;
  313. }
  314. dwRetCode = pCompiler->WinmgmtCompileFile(
  315. szFullFilename,
  316. NULL,
  317. WBEM_FLAG_DONT_ADD_TO_LIST, // autocomp, check, etc
  318. 0,
  319. 0,
  320. NULL, NULL, &Info);
  321. }
  322. }
  323. TCHAR *szNewDir = (dwRetCode?szHotMofDirBAD:szHotMofDirGOOD);
  324. TCHAR *szNewFilename = new TCHAR[lstrlen(szNewDir) + lstrlen(ffd.cFileName) + 1];
  325. if(!szNewFilename) return;
  326. CDeleteMe<TCHAR> delMe5(szNewFilename);
  327. lstrcpy(szNewFilename, szNewDir);
  328. lstrcat(szNewFilename, ffd.cFileName);
  329. //Make sure we have access to delete the old file...
  330. DWORD dwOldAttribs = GetFileAttributes(szNewFilename);
  331. if (dwOldAttribs != -1)
  332. {
  333. dwOldAttribs &= ~FILE_ATTRIBUTE_READONLY;
  334. SetFileAttributes(szNewFilename, dwOldAttribs);
  335. //Move it to directory
  336. if (DeleteFile(szNewFilename))
  337. {
  338. TRACE((LOG_WBEMCORE, "Removing old MOF %s\n", szNewFilename));
  339. }
  340. }
  341. TRACE((LOG_WBEMCORE, "Loading of MOF %s was %s. Moving to %s\n", szFullFilename, dwRetCode?"unsuccessful":"successful", szNewFilename));
  342. MoveFile(szFullFilename, szNewFilename);
  343. //Now mark the file as read only so no one deletes it!!!
  344. //Like that stops anyone deleting files :-)
  345. dwOldAttribs = GetFileAttributes(szNewFilename);
  346. if (dwOldAttribs != -1)
  347. {
  348. dwOldAttribs |= FILE_ATTRIBUTE_READONLY;
  349. SetFileAttributes(szNewFilename, dwOldAttribs);
  350. }
  351. if ((dwRetCode == 0) && (Info.dwOutFlags & AUTORECOVERY_REQUIRED))
  352. {
  353. //We need to add this item into the registry for auto-recovery purposes
  354. TRACE((LOG_WBEMCORE, "MOF %s had an auto-recover pragrma. Updating registry.\n", szNewFilename));
  355. AddToAutoRecoverList(szNewFilename);
  356. }
  357. }
  358. } while (FindNextFile(hFF, &ffd));
  359. FindClose(hFF);
  360. }
  361. if (pCompiler)
  362. pCompiler->Release();
  363. }
  364. //
  365. //
  366. // bool InitHotMofStuff
  367. //
  368. //
  369. //////////////////////////////////////////////////////////////////
  370. BOOL InitHotMofStuff( IN OUT struct _PROG_RESOURCES * pProgRes)
  371. {
  372. // Get the installation directory
  373. if (pProgRes->szHotMofDirectory)
  374. {
  375. delete [] pProgRes->szHotMofDirectory;
  376. }
  377. Registry r1(WBEM_REG_WBEM);
  378. if (r1.GetStr(__TEXT("MOF Self-Install Directory"), &pProgRes->szHotMofDirectory) == Registry::failed)
  379. {
  380. // Look for the install directory
  381. TCHAR * pWorkingDir;
  382. if (r1.GetStr(__TEXT("Installation Directory"), &pWorkingDir))
  383. {
  384. ERRORTRACE((LOG_WINMGMT,"Unable to read 'Installation Directory' from registry\n"));
  385. return false;
  386. }
  387. pProgRes->szHotMofDirectory = new TCHAR [lstrlen(pWorkingDir) + lstrlen(__TEXT("\\MOF")) +1];
  388. if(!pProgRes->szHotMofDirectory)return false;
  389. _stprintf(pProgRes->szHotMofDirectory, __TEXT("%s\\MOF"), pWorkingDir);
  390. delete pWorkingDir;
  391. if(r1.SetStr(__TEXT("MOF Self-Install Directory"), pProgRes->szHotMofDirectory) == Registry::failed)
  392. {
  393. ERRORTRACE((LOG_WINMGMT,"Unable to create 'Hot MOF Directory' in the registry\n"));
  394. return false;
  395. }
  396. }
  397. // Construct the path to the database.
  398. // ===================================
  399. WbemCreateDirectory(pProgRes->szHotMofDirectory);
  400. //Create an event on change notification for the MOF directory
  401. pProgRes->ghMofDirChange = FindFirstChangeNotification(pProgRes->szHotMofDirectory,
  402. FALSE,
  403. FILE_NOTIFY_CHANGE_FILE_NAME);
  404. if (pProgRes->ghMofDirChange == INVALID_HANDLE_VALUE)
  405. {
  406. pProgRes->ghMofDirChange = CreateEvent(NULL, FALSE, FALSE, NULL);
  407. if (pProgRes->ghMofDirChange == NULL)
  408. return false;
  409. }
  410. return true;
  411. }
  412. DWORD
  413. BuildSD( OUT PSECURITY_DESCRIPTOR *ppSD,
  414. DWORD dwSids,
  415. PSID * ArraySids,
  416. DWORD AccessType)
  417. {
  418. BOOL Status;
  419. ULONG SDLength;
  420. PACL pEventDacl = NULL;
  421. PSECURITY_DESCRIPTOR pEventSD = NULL;
  422. ULONG ulWorldAccess = 0;
  423. ULONG ulAdminAccess = 0;
  424. if (!ppSD)
  425. {
  426. return ERROR_INVALID_PARAMETER;
  427. }
  428. DWORD i;
  429. DWORD dwLenSids = 0;
  430. for (i=0;i<dwSids;i++)
  431. {
  432. dwLenSids += GetLengthSid(ArraySids[i]);
  433. }
  434. SDLength = sizeof(SECURITY_DESCRIPTOR) +
  435. (ULONG) sizeof(ACL) +
  436. (dwSids * ((ULONG) sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG))) + dwLenSids;
  437. pEventSD = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(),0,SDLength);
  438. if (pEventSD == NULL)
  439. {
  440. return ERROR_NOT_ENOUGH_MEMORY;
  441. }
  442. pEventDacl = (PACL) ((PBYTE) pEventSD + sizeof(SECURITY_DESCRIPTOR));
  443. Status = InitializeAcl( pEventDacl,
  444. SDLength - sizeof(SECURITY_DESCRIPTOR),
  445. ACL_REVISION);
  446. if (Status)
  447. {
  448. for (i=0; (i<dwSids) && Status; i++)
  449. {
  450. Status = AddAccessAllowedAce (
  451. pEventDacl,
  452. ACL_REVISION,
  453. AccessType,
  454. ArraySids[i]);
  455. }
  456. }
  457. //
  458. // Now initialize security descriptors
  459. // that export this protection
  460. //
  461. if (Status)
  462. {
  463. Status = InitializeSecurityDescriptor(pEventSD,
  464. SECURITY_DESCRIPTOR_REVISION1);
  465. if (Status)
  466. {
  467. Status = SetSecurityDescriptorDacl(
  468. pEventSD,
  469. TRUE, // DaclPresent
  470. pEventDacl,
  471. FALSE); // DaclDefaulted
  472. }
  473. }
  474. if (Status)
  475. {
  476. *ppSD = pEventSD;
  477. return NO_ERROR;
  478. }
  479. else
  480. {
  481. HeapFree(GetProcessHeap(),0,pEventSD);
  482. return GetLastError();
  483. }
  484. }
  485. BOOL
  486. SetEventDacl(HANDLE hEvent,DWORD Permission){
  487. BOOL bRet = FALSE;
  488. PSID pSidLocalSvc = NULL;
  489. SID_IDENTIFIER_AUTHORITY id = SECURITY_NT_AUTHORITY;
  490. bRet = AllocateAndInitializeSid( &id, 1,
  491. SECURITY_LOCAL_SERVICE_RID,0,0,0,0,0,0,0,&pSidLocalSvc);
  492. PSID pSidSystem = NULL;
  493. SID_IDENTIFIER_AUTHORITY id2 = SECURITY_NT_AUTHORITY;
  494. if (bRet)
  495. {
  496. bRet = AllocateAndInitializeSid( &id2, 1,
  497. SECURITY_LOCAL_SYSTEM_RID,0,0,0,0,0,0,0,&pSidSystem);
  498. };
  499. PSID pSidAdmins = NULL;
  500. SID_IDENTIFIER_AUTHORITY id3 = SECURITY_NT_AUTHORITY;
  501. if (bRet)
  502. {
  503. bRet = AllocateAndInitializeSid( &id3, 2,
  504. SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,0,&pSidAdmins);
  505. };
  506. PSID ArraySid[] = {pSidLocalSvc,pSidSystem,pSidAdmins};
  507. if (bRet)
  508. {
  509. PSECURITY_DESCRIPTOR pSD = NULL;
  510. if (NO_ERROR == BuildSD(&pSD,sizeof(ArraySid)/sizeof(PSID),ArraySid,Permission))
  511. {
  512. bRet = SetKernelObjectSecurity(hEvent,
  513. DACL_SECURITY_INFORMATION,
  514. pSD);
  515. HeapFree(GetProcessHeap(),0,pSD);
  516. }
  517. }
  518. DWORD i;
  519. for (i=0;i<sizeof(ArraySid)/sizeof(PSID);i++)
  520. {
  521. if (ArraySid[i])
  522. {
  523. FreeSid(ArraySid[i]);
  524. }
  525. }
  526. return bRet;
  527. }
  528. DWORD
  529. BuildACL( DWORD dwSids,
  530. PSID * ArraySids,
  531. DWORD * AccessType,
  532. DWORD * Flags,
  533. OUT PACL * ppACL,
  534. OUT DWORD * nBytes)
  535. {
  536. BOOL Status;
  537. ULONG ACLLength;
  538. PACL pDacl = NULL;
  539. ULONG ulWorldAccess = 0;
  540. ULONG ulAdminAccess = 0;
  541. if (!ppACL)
  542. {
  543. return ERROR_INVALID_PARAMETER;
  544. }
  545. DWORD i;
  546. DWORD dwLenSids = 0;
  547. for (i=0;i<dwSids;i++)
  548. {
  549. dwLenSids += GetLengthSid(ArraySids[i]);
  550. }
  551. ACLLength = (ULONG) sizeof(ACL) +
  552. (dwSids * ((ULONG) sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG))) + dwLenSids;
  553. pDacl = (PACL) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,ACLLength);
  554. if (pDacl == NULL)
  555. {
  556. return ERROR_NOT_ENOUGH_MEMORY;
  557. }
  558. Status = InitializeAcl( pDacl,
  559. ACLLength,
  560. ACL_REVISION);
  561. if (Status)
  562. {
  563. for (i=0; (i<dwSids) && Status; i++)
  564. {
  565. Status = AddAccessAllowedAceEx (
  566. pDacl,
  567. ACL_REVISION,
  568. Flags[i],
  569. AccessType[i],
  570. ArraySids[i]);
  571. }
  572. }
  573. if (Status)
  574. {
  575. *ppACL = pDacl;
  576. return NO_ERROR;
  577. }
  578. else
  579. {
  580. HeapFree(GetProcessHeap(),0,pDacl);
  581. return GetLastError();
  582. }
  583. }
  584. /*BOOL
  585. AddAccountToDacl(HANDLE hToken,
  586. BYTE SubCount,
  587. DWORD dw0,
  588. DWORD dw1,
  589. DWORD dw2,
  590. DWORD dw3,
  591. DWORD dw4,
  592. DWORD dw5,
  593. DWORD dw6,
  594. DWORD dw7,
  595. DWORD dwAccess,
  596. DWORD AceFlag){
  597. BOOL bRet = FALSE;
  598. DWORD i;
  599. PSID pSidAccount = NULL;
  600. SID_IDENTIFIER_AUTHORITY id = SECURITY_NT_AUTHORITY;
  601. bRet = AllocateAndInitializeSid( &id, SubCount,
  602. dw0,dw1,dw2,dw3,dw4,dw5,dw6,dw7,&pSidAccount);
  603. //
  604. //
  605. //
  606. PACL pDacl;
  607. if (bRet)
  608. {
  609. DWORD dwReq = 0;
  610. bRet = GetTokenInformation(hToken,
  611. TokenDefaultDacl,
  612. NULL,
  613. 0,
  614. &dwReq);
  615. if ((FALSE == bRet) &&
  616. (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
  617. {
  618. TOKEN_DEFAULT_DACL * pTDD = (TOKEN_DEFAULT_DACL *)_alloca(dwReq+sizeof(void*));
  619. bRet = GetTokenInformation(hToken,
  620. TokenDefaultDacl,
  621. pTDD,
  622. dwReq,
  623. &dwReq);
  624. pDacl = pTDD->DefaultDacl;
  625. }
  626. }
  627. if (!bRet)
  628. {
  629. return FALSE;
  630. }
  631. IVAN, if you plan to use this, please make sure that pDacl is
  632. initialized in all cases. There was a prefix bug on this
  633. WORD Count = pDacl->AceCount;
  634. PSID * ArraySid = (PSID *)_alloca((Count+1)*sizeof(PSID));
  635. DWORD * Access = (DWORD *)_alloca((Count+1)*sizeof(DWORD));
  636. DWORD * AceFlags = (DWORD *)_alloca((Count+1)*sizeof(DWORD));
  637. for(i=0;i<Count;i++)
  638. {
  639. ACCESS_ALLOWED_ACE * pAce;
  640. if (GetAce(pDacl,i,(PVOID *)&pAce))
  641. {
  642. PSID pSid;
  643. AllocateAndInitializeSid(&id,8,0,0,0,0,0,0,0,0,&pSid);
  644. CopySid(40,pSid,(PSID)(&pAce->SidStart));
  645. ArraySid[i] = pSid;
  646. Access[i] = pAce->Mask;
  647. AceFlags[i] = pAce->Header.AceFlags;
  648. };
  649. };
  650. ArraySid[i] = pSidAccount;
  651. Access[i] = dwAccess;
  652. AceFlags[i] = AceFlag;
  653. PACL pACL = NULL;
  654. DWORD dwBytes;
  655. if (NO_ERROR == BuildACL((Count+1),ArraySid,Access,AceFlags,&pACL,&dwBytes))
  656. {
  657. TOKEN_DEFAULT_DACL tddNew;
  658. tddNew.DefaultDacl = pACL;
  659. bRet = SetTokenInformation(hToken,
  660. TokenDefaultDacl,
  661. &tddNew,
  662. dwBytes);
  663. HeapFree(GetProcessHeap(),0,pACL);
  664. }
  665. for (i=0;i<(DWORD)(Count+1);i++)
  666. {
  667. if (ArraySid[i])
  668. {
  669. FreeSid(ArraySid[i]);
  670. }
  671. }
  672. return bRet;
  673. }
  674. */