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.

994 lines
24 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999 Microsoft Corporation
  4. //
  5. // Module Name:
  6. //
  7. // utils.c
  8. //
  9. // Abstract:
  10. //
  11. // utils functions
  12. //
  13. // Revision History:
  14. //
  15. // Thierry Perraut 04/07/1999
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. #include "stdafx.h"
  19. #include <netsh.h>
  20. #include "aaaamontr.h"
  21. #include "strdefs.h"
  22. #include "rmstring.h"
  23. #include "aaaamon.h"
  24. #include "context.h"
  25. #include <rtutils.h>
  26. #include "utils.h"
  27. #include "base64tool.h"
  28. const WCHAR c_szCurrentBuildNumber[] = L"CurrentBuildNumber";
  29. const WCHAR c_szWinVersionPath[] =
  30. L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
  31. const WCHAR c_szAssignFmt[] = L"%s = %s";
  32. const WCHAR pszAAAAEngineParamStub[] =
  33. L"SYSTEM\\CurrentControlSet\\Services\\AAAAEngine\\Parameters\\";
  34. AAAA_ALLOC_FN RutlAlloc;
  35. AAAA_DWORDDUP_FN RutlDwordDup;
  36. AAAA_CREATE_DUMP_FILE_FN RutlCreateDumpFile;
  37. AAAA_CLOSE_DUMP_FILE_FN RutlCloseDumpFile;
  38. AAAA_ASSIGN_FROM_TOKENS_FN RutlAssignmentFromTokens;
  39. AAAA_STRDUP_FN RutlStrDup;
  40. AAAA_FREE_FN RutlFree;
  41. AAAA_GET_OS_VERSION_FN RutlGetOsVersion;
  42. AAAA_GET_TAG_TOKEN_FN RutlGetTagToken;
  43. AAAA_IS_HELP_TOKEN_FN RutlIsHelpToken;
  44. //////////////////////////////////////////////////////////////////////////////
  45. // RutlGetTagToken
  46. //
  47. // Routine Description:
  48. //
  49. // Identifies each argument based on its tag. It assumes that each argument
  50. // has a tag. It also removes tag= from each argument.
  51. //
  52. // Arguments:
  53. //
  54. // ppwcArguments - The argument array. Each argument has tag=value form
  55. // dwCurrentIndex - ppwcArguments[dwCurrentIndex] is first arg.
  56. // dwArgCount - ppwcArguments[dwArgCount - 1] is last arg.
  57. // pttTagToken - Array of tag token ids that are allowed in the args
  58. // dwNumTags - Size of pttTagToken
  59. // pdwOut - Array identifying the type of each argument.
  60. //
  61. // Return Value:
  62. //
  63. // NO_ERROR, ERROR_INVALID_PARAMETER, ERROR_INVALID_OPTION_TAG
  64. //
  65. //////////////////////////////////////////////////////////////////////////////
  66. DWORD
  67. WINAPI
  68. RutlGetTagToken(
  69. IN HANDLE hModule,
  70. IN PWCHAR *ppwcArguments,
  71. IN DWORD dwCurrentIndex,
  72. IN DWORD dwArgCount,
  73. IN PTAG_TYPE pttTagToken,
  74. IN DWORD dwNumTags,
  75. OUT PDWORD pdwOut
  76. )
  77. {
  78. PWCHAR pwcTag,pwcTagVal,pwszArg = NULL;
  79. //
  80. // This function assumes that every argument has a tag
  81. // It goes ahead and removes the tag.
  82. //
  83. for ( DWORD i = dwCurrentIndex; i < dwArgCount; ++i )
  84. {
  85. DWORD len = wcslen(ppwcArguments[i]);
  86. if ( !len )
  87. {
  88. //
  89. // something wrong with arg
  90. //
  91. pdwOut[i] = static_cast<DWORD> (-1);
  92. continue;
  93. }
  94. pwszArg = static_cast<unsigned short *>(RutlAlloc(
  95. (len + 1) * sizeof(WCHAR),
  96. FALSE));
  97. if ( !pwszArg )
  98. {
  99. DisplayError(NULL, ERROR_NOT_ENOUGH_MEMORY);
  100. return ERROR_NOT_ENOUGH_MEMORY;
  101. }
  102. wcscpy(pwszArg, ppwcArguments[i]);
  103. pwcTag = wcstok(pwszArg, NETSH_ARG_DELIMITER);
  104. //
  105. // Got the first part
  106. // Now if next call returns NULL then there was no tag
  107. //
  108. pwcTagVal = wcstok((PWCHAR)NULL, NETSH_ARG_DELIMITER);
  109. if ( !pwcTagVal )
  110. {
  111. DisplayMessage(g_hModule,
  112. ERROR_NO_TAG,
  113. ppwcArguments[i]);
  114. RutlFree(pwszArg);
  115. return ERROR_INVALID_PARAMETER;
  116. }
  117. //
  118. // Got the tag. Now try to match it
  119. //
  120. BOOL bFound = FALSE;
  121. pdwOut[i - dwCurrentIndex] = (DWORD) -1;
  122. for ( DWORD j = 0; j < dwNumTags; ++j )
  123. {
  124. if ( MatchToken(pwcTag, pttTagToken[j].pwszTag) )
  125. {
  126. //
  127. // Tag matched
  128. //
  129. bFound = TRUE;
  130. pdwOut[i - dwCurrentIndex] = j;
  131. break;
  132. }
  133. }
  134. if ( bFound )
  135. {
  136. //
  137. // Remove tag from the argument
  138. //
  139. wcscpy(ppwcArguments[i], pwcTagVal);
  140. }
  141. else
  142. {
  143. DisplayError(NULL,
  144. ERROR_INVALID_OPTION_TAG,
  145. pwcTag);
  146. RutlFree(pwszArg);
  147. return ERROR_INVALID_OPTION_TAG;
  148. }
  149. RutlFree(pwszArg);
  150. }
  151. return NO_ERROR;
  152. }
  153. //////////////////////////////////////////////////////////////////////////////
  154. // RutlCreateDumpFile
  155. //////////////////////////////////////////////////////////////////////////////
  156. DWORD
  157. WINAPI
  158. RutlCreateDumpFile(
  159. IN PWCHAR pwszName,
  160. OUT PHANDLE phFile
  161. )
  162. {
  163. HANDLE hFile;
  164. *phFile = NULL;
  165. // Create/open the file
  166. hFile = CreateFileW(pwszName,
  167. GENERIC_WRITE,
  168. FILE_SHARE_READ | FILE_SHARE_DELETE,
  169. NULL,
  170. OPEN_ALWAYS,
  171. FILE_ATTRIBUTE_NORMAL,
  172. NULL);
  173. if ( hFile == INVALID_HANDLE_VALUE )
  174. {
  175. return GetLastError();
  176. }
  177. // Go to the end of the file
  178. SetFilePointer(hFile, 0, NULL, FILE_END);
  179. *phFile = hFile;
  180. return NO_ERROR;
  181. }
  182. //////////////////////////////////////////////////////////////////////////////
  183. // RutlCloseDumpFile
  184. //////////////////////////////////////////////////////////////////////////////
  185. VOID
  186. WINAPI
  187. RutlCloseDumpFile(HANDLE hFile)
  188. {
  189. CloseHandle(hFile);
  190. }
  191. //////////////////////////////////////////////////////////////////////////////
  192. //
  193. // RutlAlloc
  194. //
  195. // Returns an allocated block of memory conditionally
  196. // zeroed of the given size.
  197. //
  198. //////////////////////////////////////////////////////////////////////////////
  199. PVOID
  200. WINAPI
  201. RutlAlloc(
  202. IN DWORD dwBytes,
  203. IN BOOL bZero
  204. )
  205. {
  206. DWORD dwFlags = 0;
  207. if ( bZero )
  208. {
  209. dwFlags |= HEAP_ZERO_MEMORY;
  210. }
  211. return HeapAlloc(GetProcessHeap(), dwFlags, dwBytes);
  212. }
  213. //////////////////////////////////////////////////////////////////////////////
  214. //
  215. // RutlFree
  216. //
  217. // Conditionally free's a pointer if it is non-null
  218. //
  219. //////////////////////////////////////////////////////////////////////////////
  220. VOID
  221. WINAPI
  222. RutlFree(
  223. IN PVOID pvData
  224. )
  225. {
  226. HeapFree(GetProcessHeap(), 0, pvData);
  227. }
  228. //////////////////////////////////////////////////////////////////////////////
  229. //
  230. // RutlStrDup
  231. //
  232. // Uses RutlAlloc to copy a string
  233. //
  234. //////////////////////////////////////////////////////////////////////////////
  235. PWCHAR
  236. WINAPI
  237. RutlStrDup(
  238. IN PWCHAR pwszSrc
  239. )
  240. {
  241. PWCHAR pszRet = NULL;
  242. DWORD dwLen;
  243. if (( !pwszSrc ) || ((dwLen = wcslen(pwszSrc)) == 0))
  244. {
  245. return NULL;
  246. }
  247. pszRet = static_cast<PWCHAR>(RutlAlloc((dwLen + 1) * sizeof(WCHAR),FALSE));
  248. if ( pszRet )
  249. {
  250. wcscpy(pszRet, pwszSrc);
  251. }
  252. return pszRet;
  253. }
  254. //////////////////////////////////////////////////////////////////////////////
  255. // RutlDwordDup
  256. //
  257. // Uses RutlAlloc to copy a dword
  258. //
  259. //////////////////////////////////////////////////////////////////////////////
  260. LPDWORD
  261. WINAPI
  262. RutlDwordDup(
  263. IN DWORD dwSrc
  264. )
  265. {
  266. LPDWORD lpdwRet = NULL;
  267. lpdwRet = static_cast<LPDWORD>(RutlAlloc(sizeof(DWORD), FALSE));
  268. if ( lpdwRet )
  269. {
  270. *lpdwRet = dwSrc;
  271. }
  272. return lpdwRet;
  273. }
  274. //////////////////////////////////////////////////////////////////////////////
  275. //
  276. // RutlGetOsVersion
  277. //
  278. // Returns the build number of operating system
  279. //
  280. //////////////////////////////////////////////////////////////////////////////
  281. DWORD
  282. WINAPI
  283. RutlGetOsVersion(
  284. IN PWCHAR pwszRouter,
  285. OUT LPDWORD lpdwVersion)
  286. {
  287. DWORD dwErr, dwType = REG_SZ, dwLength;
  288. HKEY hkMachine = NULL, hkVersion = NULL;
  289. WCHAR pszBuildNumber[64];
  290. PWCHAR pszMachine = pwszRouter;
  291. //
  292. // Validate and initialize
  293. //
  294. if ( !lpdwVersion )
  295. {
  296. return ERROR_INVALID_PARAMETER;
  297. }
  298. *lpdwVersion = FALSE;
  299. do
  300. {
  301. //
  302. // Connect to the remote server
  303. //
  304. dwErr = RegConnectRegistry(
  305. pszMachine,
  306. HKEY_LOCAL_MACHINE,
  307. &hkMachine);
  308. if ( dwErr != ERROR_SUCCESS )
  309. {
  310. break;
  311. }
  312. //
  313. // Open the windows version key
  314. //
  315. dwErr = RegOpenKeyEx(
  316. hkMachine,
  317. c_szWinVersionPath,
  318. 0,
  319. KEY_QUERY_VALUE,
  320. &hkVersion
  321. );
  322. if ( dwErr != NO_ERROR )
  323. {
  324. break;
  325. }
  326. //
  327. // Read in the current version key
  328. //
  329. dwLength = sizeof(pszBuildNumber);
  330. dwErr = RegQueryValueEx (
  331. hkVersion,
  332. c_szCurrentBuildNumber,
  333. NULL,
  334. &dwType,
  335. (BYTE*)pszBuildNumber,
  336. &dwLength
  337. );
  338. if ( dwErr != NO_ERROR )
  339. {
  340. break;
  341. }
  342. *lpdwVersion = static_cast<DWORD>(wcstol(pszBuildNumber, NULL, 10));
  343. } while (FALSE);
  344. // Cleanup
  345. if ( hkVersion )
  346. {
  347. RegCloseKey( hkVersion );
  348. }
  349. if ( hkMachine )
  350. {
  351. RegCloseKey( hkMachine );
  352. }
  353. return dwErr;
  354. }
  355. //////////////////////////////////////////////////////////////////////////////
  356. //
  357. // RutlParseOptions
  358. //
  359. // Routine Description:
  360. //
  361. // Based on an array of tag types returns which options are
  362. // included in the given command line.
  363. //
  364. // Arguments:
  365. //
  366. // ppwcArguments - Argument array
  367. // dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  368. // dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  369. //
  370. // Return Value:
  371. //
  372. // NO_ERROR
  373. //
  374. //////////////////////////////////////////////////////////////////////////////
  375. DWORD
  376. WINAPI
  377. RutlParseOptions(
  378. IN PWCHAR* ppwcArguments,
  379. IN DWORD dwCurrentIndex,
  380. IN DWORD dwArgCount,
  381. IN DWORD dwNumArgs,
  382. IN TAG_TYPE* rgTags,
  383. IN DWORD dwTagCount,
  384. OUT LPDWORD* ppdwTagTypes
  385. )
  386. {
  387. LPDWORD pdwTagType;
  388. DWORD i, dwErr = NO_ERROR;
  389. // If there are no arguments, there's nothing to to
  390. //
  391. if ( !dwNumArgs )
  392. {
  393. return NO_ERROR;
  394. }
  395. // Set up the table of present options
  396. pdwTagType = static_cast<LPDWORD>(RutlAlloc(
  397. dwArgCount * sizeof(DWORD),
  398. TRUE
  399. ));
  400. if( !pdwTagType )
  401. {
  402. DisplayError(NULL, ERROR_NOT_ENOUGH_MEMORY);
  403. return ERROR_NOT_ENOUGH_MEMORY;
  404. }
  405. do {
  406. //
  407. // The argument has a tag. Assume all of them have tags
  408. //
  409. if( wcsstr(ppwcArguments[dwCurrentIndex], NETSH_ARG_DELIMITER) )
  410. {
  411. dwErr = RutlGetTagToken(
  412. g_hModule,
  413. ppwcArguments,
  414. dwCurrentIndex,
  415. dwArgCount,
  416. rgTags,
  417. dwTagCount,
  418. pdwTagType);
  419. if( dwErr != NO_ERROR )
  420. {
  421. if( dwErr == ERROR_INVALID_OPTION_TAG )
  422. {
  423. dwErr = ERROR_INVALID_SYNTAX;
  424. break;
  425. }
  426. }
  427. }
  428. else
  429. {
  430. //
  431. // No tags - all args must be in order
  432. //
  433. for( i = 0; i < dwNumArgs; ++i )
  434. {
  435. pdwTagType[i] = i;
  436. }
  437. }
  438. } while (FALSE);
  439. // Cleanup
  440. {
  441. if ( dwErr == NO_ERROR )
  442. {
  443. *ppdwTagTypes = pdwTagType;
  444. }
  445. else
  446. {
  447. RutlFree(pdwTagType);
  448. }
  449. }
  450. return dwErr;
  451. }
  452. //////////////////////////////////////////////////////////////////////////////
  453. //
  454. // RutlIsHelpToken
  455. //
  456. //////////////////////////////////////////////////////////////////////////////
  457. BOOL
  458. WINAPI
  459. RutlIsHelpToken(PWCHAR pwszToken)
  460. {
  461. if( MatchToken(pwszToken, CMD_AAAA_HELP1) )
  462. {
  463. return TRUE;
  464. }
  465. if( MatchToken(pwszToken, CMD_AAAA_HELP2) )
  466. {
  467. return TRUE;
  468. }
  469. return FALSE;
  470. }
  471. //////////////////////////////////////////////////////////////////////////////
  472. //
  473. // RutlAssignmentFromTokens
  474. //
  475. //////////////////////////////////////////////////////////////////////////////
  476. PWCHAR
  477. WINAPI
  478. RutlAssignmentFromTokens(
  479. IN HINSTANCE hModule,
  480. IN PWCHAR pwszToken,
  481. IN PWCHAR pszString
  482. )
  483. {
  484. PWCHAR pszRet = NULL, pszCmd = NULL;
  485. DWORD dwErr = NO_ERROR, dwSize;
  486. do
  487. {
  488. pszCmd = pwszToken;
  489. // Compute the string lenghth needed
  490. //
  491. dwSize = wcslen(pszString) +
  492. wcslen(pszCmd) +
  493. wcslen(c_szAssignFmt) +
  494. 1;
  495. dwSize *= sizeof(WCHAR);
  496. // Allocate the return value
  497. pszRet = (PWCHAR) RutlAlloc(dwSize, FALSE);
  498. if (pszRet == NULL)
  499. {
  500. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  501. break;
  502. }
  503. // Copy in the command assignment
  504. _snwprintf(
  505. pszRet,
  506. dwSize,
  507. c_szAssignFmt,
  508. pszCmd,
  509. pszString
  510. );
  511. } while ( FALSE );
  512. // Cleanup
  513. {
  514. if ( dwErr != NO_ERROR )
  515. {
  516. if ( pszRet )
  517. {
  518. RutlFree(pszRet);
  519. }
  520. pszRet = NULL;
  521. }
  522. }
  523. return pszRet;
  524. }
  525. //////////////////////////////////////////////////////////////////////////////
  526. //
  527. // RutlRegReadDword
  528. //
  529. //////////////////////////////////////////////////////////////////////////////
  530. DWORD
  531. RutlRegReadDword(
  532. IN HKEY hKey,
  533. IN PWCHAR pszValName,
  534. OUT LPDWORD lpdwValue
  535. )
  536. {
  537. DWORD dwSize = sizeof(DWORD), dwType = REG_DWORD, dwErr;
  538. dwErr = RegQueryValueExW(
  539. hKey,
  540. pszValName,
  541. NULL,
  542. &dwType,
  543. (LPBYTE)lpdwValue,
  544. &dwSize);
  545. if ( dwErr == ERROR_FILE_NOT_FOUND )
  546. {
  547. dwErr = NO_ERROR;
  548. }
  549. return dwErr;
  550. }
  551. //////////////////////////////////////////////////////////////////////////////
  552. //
  553. // RutlRegReadString
  554. //
  555. //////////////////////////////////////////////////////////////////////////////
  556. DWORD
  557. RutlRegReadString(
  558. IN HKEY hKey,
  559. IN PWCHAR pszValName,
  560. OUT PWCHAR* ppszValue
  561. )
  562. {
  563. DWORD dwErr = NO_ERROR, dwSize = 0;
  564. *ppszValue = NULL;
  565. // Findout how big the buffer should be
  566. //
  567. dwErr = RegQueryValueExW(
  568. hKey,
  569. pszValName,
  570. NULL,
  571. NULL,
  572. NULL,
  573. &dwSize);
  574. if ( dwErr == ERROR_FILE_NOT_FOUND )
  575. {
  576. return NO_ERROR;
  577. }
  578. if ( dwErr != ERROR_SUCCESS )
  579. {
  580. return dwErr;
  581. }
  582. // Allocate the string
  583. //
  584. *ppszValue = (PWCHAR) RutlAlloc(dwSize, TRUE);
  585. if ( ! *ppszValue )
  586. {
  587. return ERROR_NOT_ENOUGH_MEMORY;
  588. }
  589. // Read the value in and return
  590. //
  591. dwErr = RegQueryValueExW(
  592. hKey,
  593. pszValName,
  594. NULL,
  595. NULL,
  596. (LPBYTE)*ppszValue,
  597. &dwSize);
  598. return dwErr;
  599. }
  600. //////////////////////////////////////////////////////////////////////////////
  601. //
  602. // RutlRegReadString
  603. //
  604. //////////////////////////////////////////////////////////////////////////////
  605. DWORD
  606. RutlRegWriteDword(
  607. IN HKEY hKey,
  608. IN PWCHAR pszValName,
  609. IN DWORD dwValue
  610. )
  611. {
  612. return RegSetValueExW(
  613. hKey,
  614. pszValName,
  615. 0,
  616. REG_DWORD,
  617. (LPBYTE)&dwValue,
  618. sizeof(DWORD));
  619. }
  620. //////////////////////////////////////////////////////////////////////////////
  621. //
  622. // RutlRegWriteString
  623. //
  624. //////////////////////////////////////////////////////////////////////////////
  625. DWORD
  626. RutlRegWriteString(
  627. IN HKEY hKey,
  628. IN PWCHAR pszValName,
  629. IN PWCHAR pszValue
  630. )
  631. {
  632. return RegSetValueExW(
  633. hKey,
  634. pszValName,
  635. 0,
  636. REG_SZ,
  637. (LPBYTE)pszValue,
  638. (wcslen(pszValue) + 1) * sizeof(WCHAR));
  639. }
  640. //////////////////////////////////////////////////////////////////////////////
  641. //RutlParse
  642. //
  643. // Generic parse
  644. //
  645. //////////////////////////////////////////////////////////////////////////////
  646. DWORD
  647. RutlParse(
  648. IN PWCHAR* ppwcArguments,
  649. IN DWORD dwCurrentIndex,
  650. IN DWORD dwArgCount,
  651. IN BOOL* pbDone,
  652. OUT AAAAMON_CMD_ARG* pAaaaArgs,
  653. IN DWORD dwAaaaArgCount
  654. )
  655. {
  656. DWORD i, dwNumArgs, dwErr, dwLevel = 0;
  657. LPDWORD pdwTagType = NULL;
  658. TAG_TYPE* pTags = NULL;
  659. AAAAMON_CMD_ARG* pArg = NULL;
  660. if ( !dwAaaaArgCount )
  661. {
  662. return ERROR_INVALID_PARAMETER;
  663. }
  664. do
  665. {
  666. // Initialize
  667. dwNumArgs = dwArgCount - dwCurrentIndex;
  668. // Generate a list of the tags
  669. //
  670. pTags = (TAG_TYPE*)
  671. RutlAlloc(dwAaaaArgCount * sizeof(TAG_TYPE), TRUE);
  672. if ( !pTags )
  673. {
  674. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  675. break;
  676. }
  677. for ( i = 0; i < dwAaaaArgCount; ++i )
  678. {
  679. CopyMemory(&pTags[i], &pAaaaArgs[i].rgTag, sizeof(TAG_TYPE));
  680. }
  681. // Get the list of present options
  682. //
  683. dwErr = RutlParseOptions(
  684. ppwcArguments,
  685. dwCurrentIndex,
  686. dwArgCount,
  687. dwNumArgs,
  688. pTags,
  689. dwAaaaArgCount,
  690. &pdwTagType);
  691. if ( dwErr != NO_ERROR )
  692. {
  693. break;
  694. }
  695. // Copy the tag info back
  696. //
  697. for ( i = 0; i < dwAaaaArgCount; ++i )
  698. {
  699. CopyMemory(&pAaaaArgs[i].rgTag, &pTags[i], sizeof(TAG_TYPE));
  700. }
  701. for( i = 0; i < dwNumArgs; ++i )
  702. {
  703. // Validate the current argument
  704. //
  705. if ( pdwTagType[i] >= dwAaaaArgCount )
  706. {
  707. i = dwNumArgs;
  708. dwErr = ERROR_INVALID_SYNTAX;
  709. break;
  710. }
  711. pArg = &pAaaaArgs[pdwTagType[i]];
  712. // Get the value of the argument
  713. //
  714. switch ( pArg->dwType )
  715. {
  716. case AAAAMONTR_CMD_TYPE_STRING:
  717. {
  718. pArg->Val.pszValue =
  719. RutlStrDup(ppwcArguments[i + dwCurrentIndex]);
  720. break;
  721. }
  722. case AAAAMONTR_CMD_TYPE_ENUM:
  723. {
  724. dwErr = MatchEnumTag(g_hModule,
  725. ppwcArguments[i + dwCurrentIndex],
  726. pArg->dwEnumCount,
  727. pArg->rgEnums,
  728. &(pArg->Val.dwValue));
  729. if(dwErr != NO_ERROR)
  730. {
  731. RutlDispTokenErrMsg(
  732. g_hModule,
  733. EMSG_BAD_OPTION_VALUE,
  734. pArg->rgTag.pwszTag,
  735. ppwcArguments[i + dwCurrentIndex]);
  736. i = dwNumArgs;
  737. dwErr = ERROR_INVALID_PARAMETER;
  738. }
  739. break;
  740. }
  741. }
  742. if ( dwErr != NO_ERROR )
  743. {
  744. break;
  745. }
  746. // Mark the argument as present if needed
  747. //
  748. if ( pArg->rgTag.bPresent )
  749. {
  750. dwErr = ERROR_TAG_ALREADY_PRESENT;
  751. i = dwNumArgs;
  752. break;
  753. }
  754. pArg->rgTag.bPresent = TRUE;
  755. }
  756. if( dwErr != NO_ERROR )
  757. {
  758. break;
  759. }
  760. // Make sure that all of the required parameters have
  761. // been included.
  762. //
  763. for ( i = 0; i < dwAaaaArgCount; ++i )
  764. {
  765. if ( (pAaaaArgs[i].rgTag.dwRequired & NS_REQ_PRESENT)
  766. && !pAaaaArgs[i].rgTag.bPresent )
  767. {
  768. DisplayMessage(g_hModule, EMSG_CANT_FIND_EOPT);
  769. dwErr = ERROR_INVALID_SYNTAX;
  770. break;
  771. }
  772. }
  773. if ( dwErr != NO_ERROR )
  774. {
  775. break;
  776. }
  777. } while (FALSE);
  778. // Cleanup
  779. {
  780. if ( pTags )
  781. {
  782. RutlFree(pTags);
  783. }
  784. if ( pdwTagType )
  785. {
  786. RutlFree(pdwTagType);
  787. }
  788. }
  789. return dwErr;
  790. }
  791. //////////////////////////////////////////////////////////////////////////////
  792. // RefreshIASService
  793. //
  794. // Send a control 128 (refresh)to IAS
  795. //
  796. //////////////////////////////////////////////////////////////////////////////
  797. HRESULT RefreshIASService()
  798. {
  799. SC_HANDLE hManager = OpenSCManager(
  800. NULL,
  801. SERVICES_ACTIVE_DATABASE,
  802. SC_MANAGER_CONNECT |
  803. SC_MANAGER_ENUMERATE_SERVICE |
  804. SC_MANAGER_QUERY_LOCK_STATUS
  805. );
  806. if ( !hManager )
  807. {
  808. return E_FAIL;
  809. }
  810. SC_HANDLE hService = OpenServiceW(
  811. hManager,
  812. L"IAS",
  813. SERVICE_USER_DEFINED_CONTROL |
  814. SERVICE_QUERY_STATUS
  815. );
  816. if ( !hService )
  817. {
  818. CloseServiceHandle(hManager);
  819. return E_FAIL;
  820. }
  821. SERVICE_STATUS ServiceStatus;
  822. BOOL bResultOk = QueryServiceStatus(
  823. hService,
  824. &ServiceStatus
  825. );
  826. HRESULT hres;
  827. if ( bResultOk )
  828. {
  829. if ( (SERVICE_STOPPED == ServiceStatus.dwCurrentState) ||
  830. (SERVICE_STOP_PENDING == ServiceStatus.dwCurrentState))
  831. {
  832. //////////////////////////////////////////////////
  833. // service not running = nothing to do to refresh
  834. //////////////////////////////////////////////////
  835. hres = S_OK;
  836. }
  837. else
  838. {
  839. /////////////////////////////////////////////////////
  840. // the service is running thus send the refresh code
  841. /////////////////////////////////////////////////////
  842. BOOL bControlOk = ControlService(
  843. hService,
  844. 128,
  845. &ServiceStatus
  846. );
  847. if ( bControlOk == FALSE )
  848. {
  849. hres = E_FAIL;
  850. }
  851. else
  852. {
  853. hres = S_OK;
  854. }
  855. }
  856. }
  857. else
  858. {
  859. hres = E_FAIL;
  860. }
  861. //////////
  862. // clean
  863. //////////
  864. CloseServiceHandle(hService);
  865. CloseServiceHandle(hManager);
  866. // hres is always defined here.
  867. return hres;
  868. }