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.

1124 lines
31 KiB

  1. /******************************************************************************
  2. Copyright(c) Microsoft Corporation
  3. Module Name:
  4. ScheduledTasks.cpp
  5. Abstract:
  6. This module initialises the OLE library,Interfaces, & reads the input data
  7. from the command line.This module calls the appropriate functions for acheiving
  8. the functionality of different options.
  9. Author:
  10. Raghu B 10-Sep-2000
  11. Revision History:
  12. Raghu B 10-Sep-2000 : Created it
  13. G.Surender Reddy 25-sep-2000 : Modified it
  14. [ Added error checking ]
  15. G.Surender Reddy 10-oct-2000 : Modified it
  16. [ Moved the strings to Resource table ]
  17. Venu Gopal Choudary 01-Mar-2001 : Modified it
  18. [ Added -change option]
  19. Venu Gopal Choudary 12-Mar-2001 : Modified it
  20. [ Added -run and -end options]
  21. ******************************************************************************/
  22. //common header files needed for this file
  23. #include "pch.h"
  24. #include "CommonHeaderFiles.h"
  25. /******************************************************************************
  26. Routine Description:
  27. This function process the options specified in the command line & routes to
  28. different appropriate options [-create,-query,-delete,-change,-run,-end]
  29. handling functions.This is the MAIN entry point for this utility.
  30. Arguments:
  31. [ in ] argc : The count of arguments specified in the command line
  32. [ in ] argv : Array of command line arguments
  33. Return Value :
  34. A DWORD value indicating EXIT_SUCCESS on success else
  35. EXIT_FAILURE on failure
  36. ******************************************************************************/
  37. DWORD _cdecl
  38. wmain(
  39. IN DWORD argc,
  40. IN LPCTSTR argv[]
  41. )
  42. {
  43. // Declaring the main option switches as boolean values
  44. BOOL bUsage = FALSE;
  45. BOOL bCreate = FALSE;
  46. BOOL bQuery = FALSE;
  47. BOOL bDelete = FALSE;
  48. BOOL bChange = FALSE;
  49. BOOL bRun = FALSE;
  50. BOOL bEnd = FALSE;
  51. BOOL bDefVal = FALSE;
  52. DWORD dwRetStatus = EXIT_SUCCESS;
  53. HRESULT hr = S_OK;
  54. // Call the preProcessOptions function to find out the option selected by the user
  55. BOOL bValue = PreProcessOptions( argc , argv , &bUsage , &bCreate , &bQuery , &bDelete ,
  56. &bChange , &bRun , &bEnd , &bDefVal );
  57. if(bValue == FALSE)
  58. {
  59. ReleaseGlobals();
  60. return EXIT_FAILURE;
  61. }
  62. // If ScheduledTasks.exe /?
  63. if( bUsage && ( bCreate + bQuery + bDelete + bChange + bRun + bEnd ) == 0 )
  64. {
  65. displayMainUsage();
  66. ReleaseGlobals();
  67. return EXIT_SUCCESS;
  68. }
  69. // If ScheduledTasks.exe -create option is selected
  70. if( bCreate == TRUE)
  71. {
  72. hr = CreateScheduledTask( argc, argv );
  73. ReleaseGlobals();
  74. if ( FAILED(hr) )
  75. {
  76. return EXIT_FAILURE;
  77. }
  78. else
  79. {
  80. return EXIT_SUCCESS;
  81. }
  82. }
  83. // If ScheduledTasks.exe -Query option is selected
  84. if( bQuery == TRUE )
  85. {
  86. dwRetStatus = QueryScheduledTasks( argc, argv );
  87. ReleaseGlobals();
  88. return dwRetStatus;
  89. }
  90. // If ScheduledTasks.exe -delete option is selected
  91. if( bDelete == TRUE)
  92. {
  93. dwRetStatus = DeleteScheduledTask( argc, argv );
  94. ReleaseGlobals();
  95. return dwRetStatus;
  96. }
  97. // If ScheduledTasks.exe -change option is selected
  98. if( bChange == TRUE)
  99. {
  100. dwRetStatus = ChangeScheduledTaskParams( argc, argv );
  101. ReleaseGlobals();
  102. return dwRetStatus;
  103. }
  104. // If ScheduledTasks.exe -run option is selected
  105. if( bRun == TRUE)
  106. {
  107. dwRetStatus = RunScheduledTask( argc, argv );
  108. ReleaseGlobals();
  109. return dwRetStatus;
  110. }
  111. // If ScheduledTasks.exe -end option is selected
  112. if( bEnd == TRUE)
  113. {
  114. dwRetStatus = TerminateScheduledTask( argc, argv );
  115. ReleaseGlobals();
  116. return dwRetStatus;
  117. }
  118. // If ScheduledTasks.exe option is selected
  119. if( bDefVal == TRUE )
  120. {
  121. dwRetStatus = QueryScheduledTasks( argc, argv );
  122. ReleaseGlobals();
  123. return dwRetStatus;
  124. }
  125. ReleaseGlobals();
  126. return dwRetStatus;
  127. }
  128. /******************************************************************************
  129. Routine Description:
  130. This function process the options specified in the command line & routes to
  131. different appropriate functions.
  132. Arguments:
  133. [ in ] argc : The count of arguments specified in the command line
  134. [ in ] argv : Array of command line arguments
  135. [ out ] pbUsage : pointer to flag for determining [usage] -? option
  136. [ out ] pbCreate : pointer to flag for determining -create option
  137. [ out ] pbQuery : pointer to flag for determining -query option
  138. [ out ] pbDelete : pointer to flag for determining -delete option
  139. [ out ] pbChange : pointer to flag for determining -change option
  140. [ out ] pbRun : pointer to flag for determining -run option
  141. [ out ] pbEnd : pointer to flag for determining -end option
  142. [ out ] pbDefVal : pointer to flag for determining default value
  143. Return Value :
  144. A BOOL value indicating TRUE on success else FALSE
  145. ******************************************************************************/
  146. BOOL
  147. PreProcessOptions(
  148. IN DWORD argc,
  149. IN LPCTSTR argv[] ,
  150. OUT PBOOL pbUsage,
  151. OUT PBOOL pbCreate,
  152. OUT PBOOL pbQuery,
  153. OUT PBOOL pbDelete ,
  154. OUT PBOOL pbChange ,
  155. OUT PBOOL pbRun ,
  156. OUT PBOOL pbEnd ,
  157. OUT PBOOL pbDefVal
  158. )
  159. {
  160. // sub-local variables
  161. TCMDPARSER2 cmdOptions[MAX_MAIN_COMMANDLINE_OPTIONS];
  162. BOOL bReturn = FALSE;
  163. //BOOL bOthers = FALSE;
  164. // command line options
  165. const WCHAR szCreateOpt[] = L"create";
  166. const WCHAR szDeleteOpt[] = L"delete";
  167. const WCHAR szQueryOpt[] = L"query";
  168. const WCHAR szChangeOpt[] = L"change";
  169. const WCHAR szRunOpt[] = L"run";
  170. const WCHAR szEndOpt[] = L"end";
  171. const WCHAR szHelpOpt[] = L"?";
  172. TARRAY arrTemp = NULL;
  173. arrTemp = CreateDynamicArray();
  174. if( NULL == arrTemp)
  175. {
  176. SetLastError((DWORD)E_OUTOFMEMORY);
  177. SaveLastError();
  178. ShowLastErrorEx(stderr, SLE_ERROR| SLE_INTERNAL);
  179. return FALSE;
  180. }
  181. SecureZeroMemory(cmdOptions,sizeof(TCMDPARSER2) * MAX_MAIN_COMMANDLINE_OPTIONS);
  182. //
  183. // fill the commandline parser
  184. //
  185. // /? option
  186. StringCopyA( cmdOptions[ OI_USAGE ].szSignature, "PARSER2\0", 8 );
  187. cmdOptions[ OI_USAGE ].dwType = CP_TYPE_BOOLEAN;
  188. cmdOptions[ OI_USAGE ].pwszOptions = szHelpOpt;
  189. cmdOptions[ OI_USAGE ].dwCount = 1;
  190. cmdOptions[ OI_USAGE ].dwFlags = CP2_USAGE ;
  191. cmdOptions[ OI_USAGE ].pValue = pbUsage;
  192. // /create option
  193. StringCopyA( cmdOptions[ OI_CREATE ].szSignature, "PARSER2\0", 8 );
  194. cmdOptions[ OI_CREATE ].dwType = CP_TYPE_BOOLEAN;
  195. cmdOptions[ OI_CREATE ].pwszOptions = szCreateOpt;
  196. cmdOptions[ OI_CREATE ].dwCount = 1;
  197. cmdOptions[ OI_CREATE ].pValue = pbCreate;
  198. // /delete option
  199. StringCopyA( cmdOptions[ OI_DELETE ].szSignature, "PARSER2\0", 8 );
  200. cmdOptions[ OI_DELETE ].dwType = CP_TYPE_BOOLEAN;
  201. cmdOptions[ OI_DELETE ].pwszOptions = szDeleteOpt;
  202. cmdOptions[ OI_DELETE ].dwCount = 1;
  203. cmdOptions[ OI_DELETE ].dwActuals = 0;
  204. cmdOptions[ OI_DELETE ].pValue = pbDelete;
  205. // /query option
  206. StringCopyA( cmdOptions[ OI_QUERY ].szSignature, "PARSER2\0", 8 );
  207. cmdOptions[ OI_QUERY ].dwType = CP_TYPE_BOOLEAN;
  208. cmdOptions[ OI_QUERY ].pwszOptions = szQueryOpt;
  209. cmdOptions[ OI_QUERY ].dwCount = 1;
  210. cmdOptions[ OI_QUERY ].pValue = pbQuery;
  211. // /change option
  212. StringCopyA( cmdOptions[ OI_CHANGE ].szSignature, "PARSER2\0", 8 );
  213. cmdOptions[ OI_CHANGE ].dwType = CP_TYPE_BOOLEAN;
  214. cmdOptions[ OI_CHANGE ].pwszOptions = szChangeOpt;
  215. cmdOptions[ OI_CHANGE ].dwCount = 1;
  216. cmdOptions[ OI_CHANGE ].pValue = pbChange;
  217. // /run option
  218. StringCopyA( cmdOptions[ OI_RUN ].szSignature, "PARSER2\0", 8 );
  219. cmdOptions[ OI_RUN ].dwType = CP_TYPE_BOOLEAN;
  220. cmdOptions[ OI_RUN ].pwszOptions = szRunOpt;
  221. cmdOptions[ OI_RUN ].dwCount = 1;
  222. cmdOptions[ OI_RUN ].pValue = pbRun;
  223. // /end option
  224. StringCopyA( cmdOptions[ OI_END ].szSignature, "PARSER2\0", 8 );
  225. cmdOptions[ OI_END ].dwType = CP_TYPE_BOOLEAN;
  226. cmdOptions[ OI_END ].pwszOptions = szEndOpt;
  227. cmdOptions[ OI_END ].dwCount = 1;
  228. cmdOptions[ OI_END ].pValue = pbEnd;
  229. // default/sub options
  230. StringCopyA( cmdOptions[ OI_OTHERS ].szSignature, "PARSER2\0", 8 );
  231. cmdOptions[ OI_OTHERS ].dwType = CP_TYPE_TEXT;
  232. cmdOptions[ OI_OTHERS ].dwFlags = CP2_MODE_ARRAY|CP2_DEFAULT;
  233. cmdOptions[ OI_OTHERS ].pValue = &arrTemp;
  234. //parse command line arguments
  235. bReturn = DoParseParam2( argc, argv, -1, MAX_MAIN_COMMANDLINE_OPTIONS, cmdOptions, 0);
  236. if( FALSE == bReturn) // Invalid commandline
  237. {
  238. //display an error message
  239. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  240. // destroy dynamic array
  241. if(arrTemp != NULL)
  242. {
  243. DestroyDynamicArray(&arrTemp);
  244. arrTemp = NULL;
  245. }
  246. ReleaseGlobals();
  247. return FALSE;
  248. }
  249. // destroy dynamic array
  250. if(arrTemp != NULL)
  251. {
  252. DestroyDynamicArray(&arrTemp);
  253. arrTemp = NULL;
  254. }
  255. //
  256. // check for invalid syntax
  257. //
  258. if ( (( *pbCreate + *pbQuery + *pbDelete + *pbChange + *pbRun + *pbEnd ) == 0) &&
  259. (TRUE == *pbUsage) && (argc > 2) )
  260. {
  261. ShowMessage( stderr, GetResString(IDS_RES_ERROR ));
  262. return FALSE;
  263. }
  264. if(((*pbCreate + *pbQuery + *pbDelete + *pbChange + *pbRun + *pbEnd)> 1 ) ||
  265. (( *pbCreate + *pbQuery + *pbDelete + *pbChange + *pbRun + *pbEnd + *pbUsage ) == 0 ) )
  266. {
  267. if ( ( *pbCreate + *pbQuery + *pbDelete + *pbChange + *pbRun + *pbEnd + *pbUsage ) > 1 )
  268. {
  269. ShowMessage( stderr, GetResString(IDS_RES_ERROR ));
  270. return FALSE;
  271. }
  272. else if( *pbCreate == TRUE )
  273. {
  274. ShowMessage(stderr, GetResString(IDS_CREATE_USAGE));
  275. return FALSE;
  276. }
  277. else if( *pbQuery == TRUE )
  278. {
  279. ShowMessage(stderr, GetResString(IDS_QUERY_USAGE));
  280. return FALSE;
  281. }
  282. else if( *pbDelete == TRUE )
  283. {
  284. ShowMessage(stderr, GetResString(IDS_DELETE_SYNERROR));
  285. return FALSE;
  286. }
  287. else if( *pbChange == TRUE )
  288. {
  289. ShowMessage(stderr, GetResString(IDS_CHANGE_SYNERROR));
  290. return FALSE;
  291. }
  292. else if( *pbRun == TRUE )
  293. {
  294. ShowMessage(stderr, GetResString(IDS_RUN_SYNERROR));
  295. return FALSE;
  296. }
  297. else if( *pbEnd == TRUE )
  298. {
  299. ShowMessage(stderr, GetResString(IDS_END_SYNERROR));
  300. return FALSE;
  301. }
  302. else if( (!( *pbQuery )) && ( argc > 2 ) )
  303. {
  304. ShowMessage( stderr, GetResString(IDS_RES_ERROR ));
  305. return FALSE;
  306. }
  307. else
  308. {
  309. *pbDefVal = TRUE;
  310. }
  311. }
  312. return TRUE;
  313. }
  314. /******************************************************************************
  315. Routine Description:
  316. This function fetches the ITaskScheduler Interface.It also connects to
  317. the remote machine if specified & helps to operate
  318. ITaskScheduler on the specified target m/c.
  319. Arguments:
  320. [ in ] szServer : server's name
  321. Return Value :
  322. ITaskScheduler interface pointer on success else NULL
  323. ******************************************************************************/
  324. ITaskScheduler*
  325. GetTaskScheduler(
  326. IN LPCTSTR szServer
  327. )
  328. {
  329. HRESULT hr = S_OK;
  330. ITaskScheduler *pITaskScheduler = NULL;
  331. LPWSTR wszComputerName = NULL;
  332. WCHAR wszActualComputerName[ 2 * MAX_STRING_LENGTH ] = DOMAIN_U_STRING;
  333. wchar_t* pwsz = L"";
  334. WORD wSlashCount = 0 ;
  335. hr = Init( &pITaskScheduler );
  336. if( FAILED(hr))
  337. {
  338. SetLastError ((DWORD) hr);
  339. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  340. return NULL;
  341. }
  342. //If the operation is on remote machine
  343. if( IsLocalSystem(szServer) == FALSE )
  344. {
  345. wszComputerName = (LPWSTR)szServer;
  346. //check whether the server name prefixed with \\ or not.
  347. if( wszComputerName != NULL )
  348. {
  349. pwsz = wszComputerName;
  350. while ( ( *pwsz != NULL_U_CHAR ) && ( *pwsz == BACK_SLASH_U ) )
  351. {
  352. // server name prefixed with '\'..
  353. // so..increment the pointer and count number of black slashes..
  354. pwsz = _wcsinc(pwsz);
  355. wSlashCount++;
  356. }
  357. if( (wSlashCount == 2 ) ) // two back slashes are present
  358. {
  359. StringCopy( wszActualComputerName, wszComputerName, SIZE_OF_ARRAY(wszActualComputerName) );
  360. }
  361. else if ( wSlashCount == 0 )
  362. {
  363. //Append "\\" to computer name
  364. StringConcat(wszActualComputerName, wszComputerName, 2 * MAX_RES_STRING);
  365. }
  366. else
  367. {
  368. // display an error message as invalid address specified.
  369. ShowMessage (stderr, GetResString ( IDS_INVALID_NET_ADDRESS ));
  370. return NULL;
  371. }
  372. }
  373. hr = pITaskScheduler->SetTargetComputer( wszActualComputerName );
  374. }
  375. else
  376. {
  377. //Local Machine
  378. hr = pITaskScheduler->SetTargetComputer( NULL );
  379. }
  380. if( FAILED( hr ) )
  381. {
  382. SetLastError ((DWORD) hr);
  383. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  384. return NULL;
  385. }
  386. return pITaskScheduler;
  387. }
  388. /******************************************************************************
  389. Routine Description:
  390. This function initialises the COM library & fetches the ITaskScheduler interface.
  391. Arguments:
  392. [ in ] pITaskScheduler : double pointer to taskscheduler interface
  393. Return Value:
  394. A HRESULT value indicating success code else failure code
  395. ******************************************************************************/
  396. HRESULT
  397. Init(
  398. IN OUT ITaskScheduler **pITaskScheduler
  399. )
  400. {
  401. // Initalize the HRESULT value.
  402. HRESULT hr = S_OK;
  403. // Bring in the library
  404. hr = CoInitializeEx( NULL , COINIT_APARTMENTTHREADED );
  405. if (FAILED(hr))
  406. {
  407. return hr;
  408. }
  409. hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
  410. RPC_C_AUTHN_LEVEL_NONE,
  411. RPC_C_IMP_LEVEL_IMPERSONATE,
  412. NULL, EOAC_NONE, 0 );
  413. if (FAILED(hr))
  414. {
  415. CoUninitialize();
  416. return hr;
  417. }
  418. // Create the pointer to Task Scheduler object
  419. // CLSID from the header file mstask.h
  420. // Fill the task schdeuler object.
  421. hr = CoCreateInstance( CLSID_CTaskScheduler, NULL, CLSCTX_ALL,
  422. IID_ITaskScheduler,(LPVOID*) pITaskScheduler );
  423. // Should we fail, unload the library
  424. if (FAILED(hr))
  425. {
  426. CoUninitialize();
  427. }
  428. return hr;
  429. }
  430. /******************************************************************************
  431. Routine Description:
  432. This function releases the ITaskScheduler & unloads the COM library
  433. Arguments:
  434. [ in ] pITaskScheduler : pointer to the ITaskScheduler
  435. Return Value :
  436. VOID
  437. ******************************************************************************/
  438. VOID
  439. Cleanup(
  440. IN ITaskScheduler *pITaskScheduler
  441. )
  442. {
  443. if (pITaskScheduler)
  444. {
  445. pITaskScheduler->Release();
  446. }
  447. // Unload the library, now that our pointer is freed.
  448. CoUninitialize();
  449. return;
  450. }
  451. /******************************************************************************
  452. Routine Description:
  453. This function displays the main usage help of this utility
  454. Arguments:
  455. None
  456. Return Value :
  457. VOID
  458. ******************************************************************************/
  459. VOID
  460. displayMainUsage()
  461. {
  462. DisplayUsage( IDS_MAINHLP1, IDS_MAINHLP21);
  463. return;
  464. }
  465. /******************************************************************************
  466. Routine Description:
  467. This function deletes the .job extension from the task name
  468. Arguments:
  469. [ in ] lpszTaskName : Task name
  470. Return Value :
  471. None
  472. ******************************************************************************/
  473. DWORD
  474. ParseTaskName(
  475. IN LPWSTR lpszTaskName
  476. )
  477. {
  478. if(lpszTaskName == NULL)
  479. {
  480. return ERROR_INVALID_PARAMETER;
  481. }
  482. // Remove the .Job extension from the task name
  483. lpszTaskName[StringLength(lpszTaskName, 0 ) - StringLength(JOB, 0) ] = L'\0';
  484. return EXIT_SUCCESS;
  485. }
  486. /******************************************************************************
  487. Routine Description:
  488. This function displays the messages for usage of different option
  489. Arguments:
  490. [ in ] StartingMessage : First string to display
  491. [ in ] EndingMessage : Last string to display
  492. Return Value :
  493. DWORD
  494. ******************************************************************************/
  495. DWORD
  496. DisplayUsage(
  497. IN ULONG StartingMessage,
  498. IN ULONG EndingMessage
  499. )
  500. {
  501. ULONG ulCounter = 0;
  502. LPCTSTR lpszCurrentString = NULL;
  503. for( ulCounter = StartingMessage; ulCounter <= EndingMessage; ulCounter++ )
  504. {
  505. lpszCurrentString = GetResString( ulCounter );
  506. if( lpszCurrentString != NULL )
  507. {
  508. ShowMessage( stdout, _X(lpszCurrentString) );
  509. }
  510. else
  511. {
  512. return ERROR_INVALID_PARAMETER;
  513. }
  514. }
  515. return ERROR_SUCCESS;
  516. }
  517. BOOL
  518. GetGroupPolicy(
  519. IN LPWSTR szServer,
  520. IN LPWSTR szUserName,
  521. IN LPWSTR szPolicyType,
  522. OUT LPDWORD lpdwPolicy
  523. )
  524. /*++
  525. Routine Description:
  526. This function gets the value of a group policy in the registry
  527. for a specified policy type.
  528. Arguments:
  529. [ in ] szServer : Server name
  530. [ in ] szPolicyType : Policy Type
  531. [ out ] lpdwPolicy : Value of the policy
  532. Return Value :
  533. DWORD
  534. --*/
  535. {
  536. // sub-variables
  537. LONG lResult = 0;
  538. HKEY hKey = 0;
  539. HKEY hLMKey = 0;
  540. HKEY hUKey = 0;
  541. HKEY hPolicyKey = 0;
  542. PBYTE pByteData = NULL;
  543. LPWSTR wszComputerName = NULL;
  544. LPWSTR pwsz = NULL;
  545. LPWSTR pszStopStr = NULL;
  546. WCHAR wszActualComputerName[ 2 * MAX_STRING_LENGTH ];
  547. WCHAR wszBuffer[ MAX_STRING_LENGTH ];
  548. WCHAR wszSid[ MAX_STRING_LENGTH ];
  549. DWORD dwType = 0;
  550. WORD wSlashCount = 0;
  551. DWORD dwPolicy = 0;
  552. SecureZeroMemory ( wszActualComputerName, SIZE_OF_ARRAY(wszActualComputerName) );
  553. SecureZeroMemory ( wszBuffer, SIZE_OF_ARRAY(wszBuffer) );
  554. StringCopy ( wszActualComputerName, DOMAIN_U_STRING, SIZE_OF_ARRAY(wszActualComputerName) );
  555. // check whether server name prefixed with "\\" or not..If not, append the same
  556. // to the server name
  557. if ( (StringLength (szServer, 0 ) != 0) && (IsLocalSystem (szServer) == FALSE ))
  558. {
  559. wszComputerName = (LPWSTR)szServer;
  560. //check whether the server name prefixed with \\ or not.
  561. if( wszComputerName != NULL )
  562. {
  563. pwsz = wszComputerName;
  564. while ( ( *pwsz != NULL_U_CHAR ) && ( *pwsz == BACK_SLASH_U ) )
  565. {
  566. // server name prefixed with '\'..
  567. // so..increment the pointer and count number of black slashes..
  568. pwsz = _wcsinc(pwsz);
  569. wSlashCount++;
  570. }
  571. if( (wSlashCount == 2 ) ) // two back slashes are present
  572. {
  573. StringCopy( wszActualComputerName, wszComputerName, SIZE_OF_ARRAY(wszActualComputerName) );
  574. }
  575. else if ( wSlashCount == 0 )
  576. {
  577. //Append "\\" to computer name
  578. StringConcat(wszActualComputerName, wszComputerName, 2 * MAX_RES_STRING);
  579. }
  580. }
  581. DWORD cbSid = 0;
  582. DWORD cbDomainName = 0;
  583. LPWSTR szDomain = NULL;
  584. WCHAR szUser[MAX_RES_STRING+5];
  585. SID_NAME_USE peUse;
  586. PSID pSid = NULL;
  587. DWORD dwUserLength = 0;
  588. BOOL bResult = FALSE;
  589. dwUserLength = MAX_RES_STRING + 5;
  590. SecureZeroMemory (szUser, SIZE_OF_ARRAY(szUser));
  591. if ( StringLength (szUserName, 0) == 0 )
  592. {
  593. if(FALSE == GetUserName ( szUser, &dwUserLength ))
  594. {
  595. SaveLastError();
  596. return FALSE;
  597. }
  598. szUserName = szUser;
  599. }
  600. #ifdef _WIN64
  601. INT64 dwPos ;
  602. #else
  603. DWORD dwPos ;
  604. #endif
  605. pszStopStr = StrRChrI( (LPCWSTR)szUserName, NULL, L'\\' );
  606. if ( NULL != pszStopStr )
  607. {
  608. pszStopStr++;
  609. szUserName = pszStopStr;
  610. }
  611. //
  612. // Get the actual size of domain name and SID
  613. //
  614. bResult = LookupAccountName( szServer, szUserName, pSid, &cbSid, szDomain, &cbDomainName, &peUse );
  615. // API should have failed with insufficient buffer.
  616. // allocate the buffer with the actual size
  617. pSid = (PSID) AllocateMemory( cbSid );
  618. if ( pSid == NULL )
  619. {
  620. SetLastError( ERROR_OUTOFMEMORY );
  621. return FALSE;
  622. }
  623. // allocate the buffer with the actual size
  624. szDomain = (LPWSTR) AllocateMemory(cbDomainName*sizeof(WCHAR));
  625. if(NULL == szDomain)
  626. {
  627. SaveLastError();
  628. FreeMemory((LPVOID*) &pSid);
  629. return FALSE;
  630. }
  631. //Retrieve SID and Domain name for a specified computer and account names
  632. if ( FALSE == LookupAccountName( szServer, szUserName, pSid, &cbSid, szDomain, &cbDomainName, &peUse ) )
  633. {
  634. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  635. FreeMemory((LPVOID*) &pSid);
  636. FreeMemory((LPVOID*) &szDomain);
  637. return FALSE;
  638. }
  639. // Get SID string for a specified username
  640. if ( FALSE == GetSidString ( pSid, wszSid ) )
  641. {
  642. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  643. FreeMemory((LPVOID*) &pSid);
  644. FreeMemory((LPVOID*) &szDomain);
  645. return FALSE;
  646. }
  647. //release memory
  648. FreeMemory((LPVOID*) &pSid);
  649. FreeMemory((LPVOID*) &szDomain);
  650. // form the registry path to get the value for policy
  651. StringCopy ( wszBuffer, wszSid, SIZE_OF_ARRAY(wszBuffer));
  652. StringConcat ( wszBuffer, L"\\", SIZE_OF_ARRAY(wszBuffer));
  653. StringConcat ( wszBuffer, TS_KEYPOLICY_BASE, SIZE_OF_ARRAY(wszBuffer));
  654. //
  655. // Connect to the remote machine
  656. //
  657. // connect to HKEY_LOCAL_MACHINE on remote machine
  658. lResult = RegConnectRegistry( wszActualComputerName, HKEY_LOCAL_MACHINE, &hLMKey );
  659. if ( ERROR_SUCCESS != lResult )
  660. {
  661. SaveLastError();
  662. return FALSE;
  663. }
  664. // connect to HKEY_USERS on remote machine
  665. lResult = RegConnectRegistry( wszActualComputerName, HKEY_USERS, &hUKey );
  666. if ( ERROR_SUCCESS != lResult )
  667. {
  668. SaveLastError();
  669. return FALSE;
  670. }
  671. // check for NULL
  672. if (NULL != hLMKey )
  673. {
  674. //
  675. // Open the registry key
  676. //
  677. lResult = RegOpenKeyEx( hLMKey,
  678. TS_KEYPOLICY_BASE, 0, KEY_READ, &hPolicyKey );
  679. if ( NULL == hPolicyKey && NULL != hUKey)
  680. {
  681. lResult = RegOpenKeyEx( hUKey,
  682. wszBuffer, 0, KEY_READ, &hPolicyKey );
  683. }
  684. }
  685. // Get the value of a policy in the registry
  686. if ( ( NULL != hPolicyKey ) && (FALSE == GetPolicyValue (hPolicyKey, szPolicyType, &dwPolicy) ) )
  687. {
  688. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  689. if ( NULL != hPolicyKey )
  690. {
  691. RegCloseKey (hPolicyKey);
  692. hPolicyKey = NULL;
  693. }
  694. if ( NULL != hLMKey )
  695. {
  696. RegCloseKey (hLMKey);
  697. hLMKey = NULL;
  698. }
  699. if ( NULL != hUKey )
  700. {
  701. RegCloseKey (hUKey);
  702. hUKey = NULL;
  703. }
  704. return FALSE;
  705. }
  706. // release all the keys
  707. if ( NULL != hPolicyKey )
  708. {
  709. RegCloseKey (hPolicyKey);
  710. hPolicyKey = NULL;
  711. }
  712. if ( NULL != hLMKey )
  713. {
  714. RegCloseKey (hLMKey);
  715. hLMKey = NULL;
  716. }
  717. if ( NULL != hUKey )
  718. {
  719. RegCloseKey (hUKey);
  720. hUKey = NULL;
  721. }
  722. }
  723. else
  724. {
  725. //
  726. // Open the registry key for HKEY_LOCAL_MACHINE
  727. //
  728. lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  729. TS_KEYPOLICY_BASE, 0, KEY_READ, &hKey );
  730. if( lResult != ERROR_SUCCESS)
  731. {
  732. // check the keyvalue
  733. if ( NULL == hKey )
  734. {
  735. //
  736. // Open the registry key for HKEY_CURRENT_USER
  737. //
  738. lResult = RegOpenKeyEx( HKEY_CURRENT_USER,
  739. TS_KEYPOLICY_BASE, 0, KEY_READ, &hKey );
  740. }
  741. }
  742. // Get the value of a policy in the registry
  743. if ( ( NULL != hKey ) && (FALSE == GetPolicyValue (hKey, szPolicyType, &dwPolicy) ))
  744. {
  745. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  746. // release the resource
  747. if ( NULL != hKey )
  748. {
  749. RegCloseKey (hKey);
  750. }
  751. return FALSE;
  752. }
  753. // check for NULL
  754. if ( NULL != hKey )
  755. {
  756. RegCloseKey (hKey);
  757. }
  758. }
  759. // assign the value
  760. *lpdwPolicy = dwPolicy;
  761. // return success
  762. return TRUE;
  763. }
  764. BOOL
  765. GetPolicyValue(
  766. IN HKEY hKey,
  767. IN LPWSTR szPolicyType,
  768. OUT LPDWORD lpdwPolicy
  769. )
  770. /*++
  771. Routine Description:
  772. This function gets the value of a group policy in the registry
  773. for a given Register Key
  774. Arguments:
  775. [ in ] hKey : Register Key
  776. [ in ] szPolicyType : Policy Type
  777. [ out ] lpdwPolicy : Value of the policy
  778. Return Value :
  779. BOOL
  780. --*/
  781. {
  782. // sub-variables
  783. LONG lResult = 0;
  784. DWORD dwLength = 0;
  785. LPBYTE pByteData = NULL;
  786. DWORD dwType = 0;
  787. // get the size of the buffer to hold the value associated with the value name
  788. lResult = RegQueryValueEx( hKey, szPolicyType, NULL, NULL, NULL, &dwLength );
  789. // allocate the buffer
  790. pByteData = (LPBYTE) AllocateMemory( (dwLength + 10) * sizeof( BYTE ) );
  791. if ( pByteData == NULL )
  792. {
  793. SetLastError( ERROR_OUTOFMEMORY );
  794. return FALSE;
  795. }
  796. // now get the data
  797. lResult = RegQueryValueEx( hKey, szPolicyType, NULL, &dwType, pByteData, &dwLength );
  798. *lpdwPolicy = *((DWORD*) pByteData);
  799. FreeMemory( (LPVOID*) &pByteData );
  800. return TRUE;
  801. }
  802. BOOL
  803. GetSidString (
  804. IN PSID pSid,
  805. OUT LPWSTR wszSid
  806. )
  807. /*++
  808. Routine Description:
  809. This function gets the SID string.
  810. Arguments:
  811. [IN] PSID pSid : SID structure
  812. [OUT] LPWSTR wszSid : Stores SID string
  813. Return Value:
  814. TRUE On success
  815. FALSE On failure
  816. --*/
  817. {
  818. // sub-local variables
  819. PSID_IDENTIFIER_AUTHORITY Auth ;
  820. PUCHAR lpNbSubAuth ;
  821. LPDWORD lpSubAuth = 0 ;
  822. UCHAR uloop ;
  823. WCHAR wszTmp[MAX_RES_STRING] ;
  824. WCHAR wszStr[ MAX_RES_STRING ] ;
  825. // initialize the variables
  826. SecureZeroMemory ( wszTmp, SIZE_OF_ARRAY(wszTmp) );
  827. SecureZeroMemory ( wszStr, SIZE_OF_ARRAY(wszStr) );
  828. //Add the revision
  829. StringCopy ( wszStr, SID_STRING, MAX_RES_STRING );
  830. //Get identifier authority
  831. Auth = GetSidIdentifierAuthority ( pSid ) ;
  832. if ( NULL == Auth )
  833. {
  834. SaveLastError();
  835. return FALSE ;
  836. }
  837. // format authority value
  838. if ( (Auth->Value[0] != 0) || (Auth->Value[1] != 0) ) {
  839. StringCchPrintf ( wszTmp, SIZE_OF_ARRAY(wszTmp), AUTH_FORMAT_STR1 ,
  840. (ULONG)Auth->Value[0],
  841. (ULONG)Auth->Value[1],
  842. (ULONG)Auth->Value[2],
  843. (ULONG)Auth->Value[3],
  844. (ULONG)Auth->Value[4],
  845. (ULONG)Auth->Value[5] );
  846. }
  847. else {
  848. StringCchPrintf ( wszTmp, SIZE_OF_ARRAY(wszTmp), AUTH_FORMAT_STR2 ,
  849. (ULONG)(Auth->Value[5] ) +
  850. (ULONG)(Auth->Value[4] << 8) +
  851. (ULONG)(Auth->Value[3] << 16) +
  852. (ULONG)(Auth->Value[2] << 24) );
  853. }
  854. StringConcat (wszStr, DASH , SIZE_OF_ARRAY(wszStr));
  855. StringConcat (wszStr, wszTmp, SIZE_OF_ARRAY(wszStr));
  856. //Get sub authorities
  857. lpNbSubAuth = GetSidSubAuthorityCount ( pSid ) ;
  858. if ( NULL == lpNbSubAuth )
  859. {
  860. SaveLastError();
  861. return FALSE ;
  862. }
  863. // loop through and get sub authority
  864. for ( uloop = 0 ; uloop < *lpNbSubAuth ; uloop++ ) {
  865. lpSubAuth = GetSidSubAuthority ( pSid,(DWORD)uloop ) ;
  866. if ( NULL == lpSubAuth )
  867. {
  868. SaveLastError();
  869. return FALSE;
  870. }
  871. // convert long integer to a string
  872. _ultot (*lpSubAuth, wszTmp, BASE_TEN) ;
  873. StringConcat ( wszStr, DASH, SIZE_OF_ARRAY(wszStr) ) ;
  874. StringConcat (wszStr, wszTmp, SIZE_OF_ARRAY(wszStr) ) ;
  875. }
  876. StringCopy ( wszSid, wszStr, MAX_RES_STRING );
  877. // retunr success
  878. return TRUE ;
  879. }