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.

1385 lines
45 KiB

  1. //-------------------------------------------------------------------
  2. //
  3. // FILE: LicCpa.cpp
  4. //
  5. // Summary;
  6. // This file contians the DLL & CPL entry points, F1 Help message
  7. // hooking, and misc common dialog functions.
  8. //
  9. // Entry Points;
  10. // CPlSetup
  11. // CPlApplet
  12. // DllMain
  13. //
  14. // History;
  15. // Nov-30-94 MikeMi Created
  16. // Mar-14-95 MikeMi Added F1 Message Filter and PWM_HELP message
  17. // Apr-26-95 MikeMi Added Computer name and remoting
  18. // Dec-12-95 JeffParh Added secure certificate support
  19. //
  20. //-------------------------------------------------------------------
  21. #include <windows.h>
  22. #include <cpl.h>
  23. #include "resource.h"
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include "PriDlgs.hpp"
  27. #include "SecDlgs.hpp"
  28. #include "liccpa.hpp"
  29. #include "Special.hpp"
  30. #include <strsafe.h>
  31. extern "C"
  32. {
  33. BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved);
  34. BOOL APIENTRY CPlSetup( DWORD nArgs, LPSTR apszArgs[], LPSTR *ppszResult );
  35. LONG CALLBACK CPlApplet( HWND hwndCPL, UINT uMsg, LPARAM lParam1, LPARAM lParam2);
  36. LRESULT CALLBACK msgprocHelpFilter( int nCode, WPARAM wParam, LPARAM lParam );
  37. }
  38. // Setup routines
  39. //
  40. const CHAR szSETUP_NORMAL[] = "FULLSETUP";
  41. const CHAR szSETUP_PERSEAT[] = "PERSEAT";
  42. const CHAR szSETUP_UNATTENDED[] = "UNATTENDED";
  43. const CHAR szSETUP_NORMALNOEXIT[] = "FULLSETUPNOEXIT";
  44. const CHAR szREMOTESETUP_NORMAL[] = "REMOTEFULLSETUP";
  45. const CHAR szREMOTESETUP_PERSEAT[] = "REMOTEPERSEAT";
  46. const CHAR szREMOTESETUP_UNATTENDED[] = "REMOTEUNATTENDED";
  47. const CHAR szREMOTESETUP_NORMALNOEXIT[] = "REMOTEFULLSETUPNOEXIT";
  48. // Modes for unattended setup
  49. //
  50. const CHAR szUNATTENDED_PERSEAT[] = "PERSEAT";
  51. const CHAR szUNATTENDED_PERSERVER[] = "PERSERVER";
  52. // Certificate required / not required
  53. const CHAR szSETUP_CERTREQUIRED[] = "CERTREQUIRED";
  54. const CHAR szSETUP_CERTNOTREQUIRED[] = "CERTNOTREQUIRED";
  55. // Use default help file
  56. const CHAR szSETUP_DEFAULTHELP[] = "DEFAULTHELP";
  57. // Setup Error return strings
  58. //
  59. static CHAR szSETUP_EXIT[] = "EXIT";
  60. static CHAR szSETUP_ERROR[] = "ERROR";
  61. static CHAR szSETUP_SECURITY[] = "SECURITY";
  62. static CHAR szSETUP_NOREMOTE[] = "NOREMOTE";
  63. static CHAR szSETUP_DOWNLEVEL[] = "DOWNLEVEL";
  64. static CHAR szSETUP_OK[] = "OK";
  65. // Registered help message for F1 hooking
  66. //
  67. const WCHAR szF1HELPMESSAGE[] = L"LicCpaF1Help";
  68. HINSTANCE g_hinst = NULL; // global hinstance of this dll
  69. HHOOK g_hhook = NULL; // global hhook for F1 message filter
  70. UINT PWM_HELP = 0; // global help message when F1 is pressed
  71. //-------------------------------------------------------------------
  72. //
  73. // Function: msgprocHelpFilter
  74. //
  75. // Summary;
  76. // This functions will filter the messages looking for F1, then send
  77. // the registered message to the top most parent of that window
  78. // informing it that F1 for help was pressed.
  79. //
  80. // Arguments;
  81. // (see Win32 MessageProc)
  82. //
  83. // History;
  84. // Mar-13-95 MikeMi Created
  85. //
  86. //-------------------------------------------------------------------
  87. LRESULT CALLBACK msgprocHelpFilter( int nCode, WPARAM wParam, LPARAM lParam )
  88. {
  89. LRESULT lrt = 0;
  90. PMSG pmsg = (PMSG)lParam;
  91. if (nCode < 0)
  92. {
  93. lrt = CallNextHookEx( g_hhook, nCode, wParam, lParam );
  94. }
  95. else
  96. {
  97. if (MSGF_DIALOGBOX == nCode)
  98. {
  99. // handle F1 key
  100. if ( (WM_KEYDOWN == pmsg->message) &&
  101. (VK_F1 == (INT_PTR)pmsg->wParam) )
  102. {
  103. HWND hwnd = pmsg->hwnd;
  104. // post message to parent that handles help
  105. while( GetWindowLong( hwnd, GWL_STYLE ) & WS_CHILD )
  106. {
  107. hwnd = GetParent( hwnd );
  108. }
  109. PostMessage( hwnd, PWM_HELP, 0, 0 );
  110. lrt = 1;
  111. }
  112. }
  113. }
  114. return( lrt );
  115. }
  116. //-------------------------------------------------------------------
  117. //
  118. // Function: InstallF1Hook
  119. //
  120. // Summary;
  121. // This will ready the message filter for handling F1.
  122. // It install the message hook and registers a message that will
  123. // be posted to the dialogs.
  124. //
  125. // Arguments;
  126. // hinst [in] - the module handle of this DLL (needed to install hook)
  127. // dwThreadId [in] - thread to attach filter to
  128. //
  129. // Notes:
  130. // The control.exe does this work and sends the "ShellHelp" message.
  131. // A seperate F1 message filter is needed because these dialogs maybe
  132. // raised by other applications than control.exe.
  133. //
  134. // History;
  135. // Mar-13-95 MikeMi Created
  136. //
  137. //-------------------------------------------------------------------
  138. BOOL InstallF1Hook( HINSTANCE hInst, DWORD dwThreadId )
  139. {
  140. BOOL frt = FALSE;
  141. if (NULL == g_hhook)
  142. {
  143. g_hhook = SetWindowsHookEx( WH_MSGFILTER,
  144. (HOOKPROC)msgprocHelpFilter,
  145. hInst,
  146. dwThreadId );
  147. if (NULL != g_hhook)
  148. {
  149. PWM_HELP = RegisterWindowMessage( szF1HELPMESSAGE );
  150. if (0 != PWM_HELP)
  151. {
  152. frt = TRUE;
  153. }
  154. }
  155. }
  156. return( frt );
  157. }
  158. //-------------------------------------------------------------------
  159. //
  160. // Function: RemoveF1Hook
  161. //
  162. // Summary;
  163. // This will remove the message filter hook that InstallF1Hook installs.
  164. //
  165. // History;
  166. // Mar-13-95 MikeMi Created
  167. //
  168. //-------------------------------------------------------------------
  169. BOOL RemoveF1Hook( )
  170. {
  171. BOOL frt = UnhookWindowsHookEx( g_hhook );
  172. g_hhook = NULL;
  173. return( frt );
  174. }
  175. //-------------------------------------------------------------------
  176. //
  177. // Function: DLLMain
  178. //
  179. // Summary;
  180. // Entry point for all DLLs
  181. //
  182. // Notes:
  183. // We only support being called from the same thread that called
  184. // LoadLibrary. Because we install a message hook, and passing a
  185. // zero for threadid does not work as documented.
  186. //
  187. // History;
  188. // Nov-30-94 MikeMi Created
  189. //
  190. //-------------------------------------------------------------------
  191. BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  192. {
  193. UNREFERENCED_PARAMETER(lpReserved);
  194. BOOL frt = TRUE;
  195. switch (dwReason)
  196. {
  197. case DLL_PROCESS_ATTACH:
  198. g_hinst = hInstance;
  199. frt = InstallF1Hook( g_hinst, GetCurrentThreadId() );
  200. break;
  201. case DLL_PROCESS_DETACH:
  202. RemoveF1Hook();
  203. break;
  204. case DLL_THREAD_ATTACH:
  205. break;
  206. case DLL_THREAD_DETACH:
  207. break;
  208. default:
  209. break;
  210. }
  211. return( frt );
  212. }
  213. //-------------------------------------------------------------------
  214. //
  215. // Function: LowMemoryDlg
  216. //
  217. // Summary;
  218. // Standard function for handling low memory situation
  219. //
  220. // History;
  221. // Nov-30-94 MikeMi Created
  222. //
  223. //-------------------------------------------------------------------
  224. void LowMemoryDlg()
  225. {
  226. WCHAR szText[TEMPSTR_SIZE];
  227. WCHAR szTitle[TEMPSTR_SIZE];
  228. LoadString(g_hinst, IDS_CPATITLE, szTitle, TEMPSTR_SIZE);
  229. LoadString(g_hinst, IDS_LOWMEM, szText, TEMPSTR_SIZE);
  230. MessageBox (NULL, szText, szTitle, MB_OK|MB_ICONEXCLAMATION);
  231. }
  232. //-------------------------------------------------------------------
  233. //
  234. // Function: BadRegDlg
  235. //
  236. // Summary;
  237. // Standard function for handling bad registry situation
  238. //
  239. // History;
  240. // Nov-30-94 MikeMi Created
  241. //
  242. //-------------------------------------------------------------------
  243. void BadRegDlg( HWND hwndDlg )
  244. {
  245. WCHAR szText[TEMPSTR_SIZE];
  246. WCHAR szTitle[TEMPSTR_SIZE];
  247. LoadString(g_hinst, IDS_CPATITLE, szTitle, TEMPSTR_SIZE);
  248. LoadString(g_hinst, IDS_BADREGTERM, szText, TEMPSTR_SIZE);
  249. MessageBox (hwndDlg, szText, szTitle, MB_OK|MB_ICONEXCLAMATION);
  250. }
  251. //-------------------------------------------------------------------
  252. //
  253. // Function: CenterDialogToScreen
  254. //
  255. // Summary;
  256. // Move the window so that it is centered on the screen
  257. //
  258. // Arguments;
  259. // hwndDlg [in] - the hwnd to the dialog to center
  260. //
  261. // History;
  262. // Dec-3-94 MikeMi Created
  263. //
  264. //-------------------------------------------------------------------
  265. void CenterDialogToScreen( HWND hwndDlg )
  266. {
  267. RECT rcDlg;
  268. INT x, y, w, h;
  269. INT sw, sh;
  270. sw = GetSystemMetrics( SM_CXSCREEN );
  271. sh = GetSystemMetrics( SM_CYSCREEN );
  272. GetWindowRect( hwndDlg, &rcDlg );
  273. w = rcDlg.right - rcDlg.left;
  274. h = rcDlg.bottom - rcDlg.top;
  275. x = (sw / 2) - (w / 2);
  276. y = (sh / 2) - (h / 2);
  277. MoveWindow( hwndDlg, x, y, w, h, FALSE );
  278. }
  279. //-------------------------------------------------------------------
  280. //
  281. // Function: InitStaticWithService
  282. // Summary;
  283. // Handle the initialization of a static text with a service name
  284. //
  285. // Arguments;
  286. // hwndDlg [in] - the dialog that contains the static
  287. // wID [in] - the id of the static control
  288. // pszService [in] - the service display name to use
  289. //
  290. // Notes;
  291. //
  292. // History;
  293. // Dec-05-1994 MikeMi Created
  294. //
  295. //-------------------------------------------------------------------
  296. void InitStaticWithService( HWND hwndDlg, UINT wID, LPCWSTR pszService )
  297. {
  298. WCHAR szText[LTEMPSTR_SIZE];
  299. WCHAR szTemp[LTEMPSTR_SIZE];
  300. GetDlgItemText( hwndDlg, wID, szTemp, LTEMPSTR_SIZE );
  301. HRESULT hr = StringCbPrintf( szText, sizeof(szText), szTemp, pszService );
  302. if (SUCCEEDED(hr))
  303. SetDlgItemText( hwndDlg, wID, szText );
  304. }
  305. //-------------------------------------------------------------------
  306. //
  307. // Function: InitStaticWithService2
  308. // Summary;
  309. // Handle the initialization of a static text that contians two
  310. // instances of a service name with the service name
  311. //
  312. // Arguments;
  313. // hwndDlg [in] - the dialog that contains the static
  314. // wID [in] - the id of the static control
  315. // pszService [in] - the service display name to use
  316. //
  317. // Notes;
  318. //
  319. // History;
  320. // Dec-05-1994 MikeMi Created
  321. //
  322. //-------------------------------------------------------------------
  323. void InitStaticWithService2( HWND hwndDlg, UINT wID, LPCWSTR pszService )
  324. {
  325. WCHAR szText[LTEMPSTR_SIZE];
  326. WCHAR szTemp[LTEMPSTR_SIZE];
  327. GetDlgItemText( hwndDlg, wID, szTemp, LTEMPSTR_SIZE );
  328. HRESULT hr = StringCbPrintf( szText, sizeof(szText), szTemp, pszService, pszService );
  329. if (SUCCEEDED(hr))
  330. SetDlgItemText( hwndDlg, wID, szText );
  331. }
  332. //-------------------------------------------------------------------
  333. //
  334. // Function: CPlApplet
  335. //
  336. // Summary;
  337. // Entry point for Comntrol Panel Applets
  338. //
  339. // Arguments;
  340. // hwndCPL [in] - handle of Control Panel window
  341. // uMsg [in] - message
  342. // lParam1 [in] - first message parameter, usually the application number
  343. // lParam2 [in] - second message parameter
  344. //
  345. // Return;
  346. // message dependant
  347. //
  348. // Notes;
  349. //
  350. // History;
  351. // Nov-11-1994 MikeMi Created
  352. //
  353. //-------------------------------------------------------------------
  354. LONG CALLBACK CPlApplet( HWND hwndCPL, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
  355. {
  356. LPCPLINFO lpCPlInfo;
  357. LONG_PTR iApp;
  358. LONG lrt = 0;
  359. iApp = (LONG_PTR) lParam1;
  360. switch (uMsg)
  361. {
  362. case CPL_INIT: /* first message, sent once */
  363. //
  364. // Initialize global special version information is this liccpa
  365. // is a special version (eg: restricted SAM, NFR, etc).
  366. //
  367. InitSpecialVersionInfo();
  368. lrt = TRUE;
  369. break;
  370. case CPL_GETCOUNT: /* second message, sent once */
  371. lrt = 1; // we support only one application within this DLL
  372. break;
  373. case CPL_INQUIRE: /* third message, sent once per app */
  374. lpCPlInfo = (LPCPLINFO) lParam2;
  375. lpCPlInfo->idIcon = IDI_LICCPA;
  376. lpCPlInfo->idName = IDS_CPATITLE;
  377. lpCPlInfo->idInfo = IDS_CPADESC;
  378. lpCPlInfo->lData = 0;
  379. break;
  380. case CPL_SELECT: /* application icon selected */
  381. lrt = 1;
  382. break;
  383. case CPL_DBLCLK: /* application icon double-clicked */
  384. //
  385. // Check if this is a special version of liccpa.
  386. //
  387. if (gSpecVerInfo.idsSpecVerWarning)
  388. {
  389. RaiseNotAvailWarning( hwndCPL );
  390. break;
  391. }
  392. CpaDialog( hwndCPL );
  393. break;
  394. case CPL_STOP: /* sent once per app. before CPL_EXIT */
  395. break;
  396. case CPL_EXIT: /* sent once before FreeLibrary called */
  397. break;
  398. default:
  399. break;
  400. }
  401. return( lrt );
  402. }
  403. //-------------------------------------------------------------------
  404. //
  405. // Function: CreateWSTR
  406. //
  407. // Summary;
  408. // Given a STR (ASCII or MB), allocate and translate to WSTR
  409. //
  410. // Arguments;
  411. // ppszWStr [out] - allocated & converted string
  412. // pszStr [in] - string to convert
  413. //
  414. // Return: TRUE if allocated and converted, FALSE if failed
  415. //
  416. // History;
  417. // Nov-30-94 MikeMi Created
  418. //
  419. //-------------------------------------------------------------------
  420. BOOL CreateWSTR( LPWSTR* ppszWStr, LPSTR pszStr )
  421. {
  422. size_t cchConv;
  423. LPWSTR pszConv;
  424. BOOL frt = FALSE;
  425. WCHAR pszTemp[LTEMPSTR_SIZE];
  426. if (NULL == pszStr)
  427. {
  428. *ppszWStr = NULL;
  429. frt = TRUE;
  430. }
  431. else
  432. {
  433. #ifdef FE_SB
  434. // Since there was a problem in Server setup when calling setlocale or
  435. // linking C-runtime lib, we used Win32 API instead of mbstowcs.
  436. cchConv = ::MultiByteToWideChar(CP_ACP, 0,
  437. pszStr, -1,
  438. NULL, 0);
  439. pszConv = (LPWSTR)::GlobalAlloc( GPTR, cchConv * sizeof( WCHAR ) );
  440. if (NULL != pszConv)
  441. {
  442. ::MultiByteToWideChar(CP_ACP, 0,
  443. pszStr, -1,
  444. pszConv, cchConv);
  445. *ppszWStr = pszConv;
  446. frt = TRUE;
  447. }
  448. #else
  449. cchConv = mbstowcs( pszTemp, pszStr, LTEMPSTR_SIZE );
  450. cchConv++;
  451. pszConv = (LPWSTR)GlobalAlloc( GPTR, cchConv * sizeof( WCHAR ) );
  452. if (NULL != pszConv)
  453. {
  454. HRESULT hr = StringCchCopy( pszConv, cchConv, pszTemp );
  455. if (SUCCEEDED(hr))
  456. {
  457. *ppszWStr = pszConv;
  458. frt = TRUE;
  459. }
  460. }
  461. #endif
  462. }
  463. return( frt );
  464. }
  465. //-------------------------------------------------------------------
  466. //
  467. // Function: Setup
  468. //
  469. // Summary;
  470. // Run normal setup or Perseat Setup
  471. //
  472. // Arguments
  473. // nArgs [in] - The number of arguments in the apszArgs array
  474. // If this value is 5, help button will call common help
  475. // If this value is 9, help button will call the passed help
  476. // apszArgs[] [in] - The argumnents passed in,
  477. // [0] szRoutine - The type of setup to run (FullSetup | PerSeatSetup)
  478. // [1] szHwnd - The parent Window handle, in HEX!
  479. // [2] szService - The Reg Key name of the service
  480. // [3] szFamilyDisplayName - The family display name of the service
  481. // [4] szDisplayName - The display name of the service
  482. // [5] szHelpFile - The complete path and name to help file
  483. // leave as an empty string to remove help buttons
  484. // [6] szHelpContext - the DWORD to use as the main help context
  485. // [7] szHCPerSeat - the DWORD to use as the PerSeat Help context
  486. // [8] szHCPerServer - the DWORD to use as the PerServer help context
  487. //
  488. // Return:
  489. // 0 - sucessfull
  490. // ERR_HELPPARAMS
  491. // ERR_HWNDPARAM
  492. // ERR_SERVICEPARAM
  493. // ERR_NUMPARAMS
  494. // ERR_CLASSREGFAILED
  495. // ERR_INVALIDROUTINE
  496. // ERR_INVALIDMODE
  497. //
  498. // Notes:
  499. //
  500. // History:
  501. // Nov-17-94 MikeMi Created
  502. //
  503. //-------------------------------------------------------------------
  504. const int SETUPARG_SETUP = 0;
  505. const int SETUPARG_HWND = 1;
  506. const int SETUPARG_SERVICE = 2;
  507. const int SETUPARG_FAMILYNAME = 3;
  508. const int SETUPARG_NAME = 4;
  509. const int SETUPARG_HELPFILE = 5;
  510. const int SETUPARG_HELPCONTEXT = 6;
  511. const int SETUPARG_HCPERSEAT = 7;
  512. const int SETUPARG_HCPERSERVER = 8;
  513. const int SETUPARG_CERTREQUIRED = 9;
  514. const int SETUPARG_WOOPTIONAL = 5; // count of args without optional
  515. const int SETUPARG_WOPTIONAL = 9; // count of args with optional
  516. const int SETUPARG_WOPTIONALEX = 10; // count of args with optional + certrequired extension
  517. #pragma warning (push)
  518. #pragma warning (disable : 4127) //avoid warning on while false
  519. INT_PTR Setup( DWORD nArgs, LPSTR apszArgs[] )
  520. {
  521. SETUPDLGPARAM dlgParam;
  522. INT_PTR nError = 0;
  523. HWND hwndParent = NULL;
  524. BOOL fCustomHelp = FALSE;
  525. BOOL bCertRequired = FALSE;
  526. dlgParam.pszHelpFile = (LPWSTR)LICCPA_HELPFILE;
  527. dlgParam.dwHelpContext = LICCPA_HELPCONTEXTMAINSETUP;
  528. dlgParam.dwHCPerServer = LICCPA_HELPCONTEXTPERSERVER;
  529. dlgParam.dwHCPerSeat = LICCPA_HELPCONTEXTPERSEAT;
  530. dlgParam.pszService = NULL;
  531. dlgParam.pszComputer = NULL;
  532. dlgParam.fNoExit = FALSE;
  533. do
  534. {
  535. if ((nArgs == SETUPARG_WOPTIONAL) || (nArgs == SETUPARG_WOOPTIONAL) || (nArgs == SETUPARG_WOPTIONALEX))
  536. {
  537. if (nArgs > SETUPARG_WOOPTIONAL)
  538. {
  539. if ( ( NULL != apszArgs[SETUPARG_HELPFILE] ) && lstrcmpiA( apszArgs[SETUPARG_HELPFILE], szSETUP_DEFAULTHELP ) )
  540. {
  541. // help file given
  542. LPWSTR pszHelpFile;
  543. if ( CreateWSTR( &pszHelpFile, apszArgs[SETUPARG_HELPFILE] ) )
  544. {
  545. if (0 == lstrlen( pszHelpFile ))
  546. {
  547. GlobalFree( (HGLOBAL)pszHelpFile );
  548. dlgParam.pszHelpFile = NULL; // should remove help buttons
  549. }
  550. else
  551. {
  552. fCustomHelp = TRUE;
  553. dlgParam.pszHelpFile = pszHelpFile;
  554. }
  555. }
  556. else
  557. {
  558. nError = ERR_HELPPARAMS;
  559. break;
  560. }
  561. dlgParam.dwHelpContext = (DWORD)strtoul( apszArgs[SETUPARG_HELPCONTEXT], NULL, 0);
  562. dlgParam.dwHCPerSeat = (DWORD)strtoul( apszArgs[SETUPARG_HCPERSEAT], NULL, 0);
  563. dlgParam.dwHCPerServer = (DWORD)strtoul( apszArgs[SETUPARG_HCPERSERVER], NULL, 0);
  564. }
  565. if ( nArgs > SETUPARG_CERTREQUIRED )
  566. {
  567. // cert required / not required given
  568. if ( !lstrcmpiA( szSETUP_CERTREQUIRED, apszArgs[SETUPARG_CERTREQUIRED] ) )
  569. {
  570. bCertRequired = TRUE;
  571. }
  572. else if ( lstrcmpiA( szSETUP_CERTNOTREQUIRED, apszArgs[SETUPARG_CERTREQUIRED] ) )
  573. {
  574. // unrecognized argument for cert required/not required
  575. nError = ERR_CERTREQPARAM;
  576. break;
  577. }
  578. }
  579. }
  580. // hwnd is in hex!
  581. #ifdef _WIN64
  582. {
  583. _int64 val = 0;
  584. sscanf(apszArgs[SETUPARG_HWND], "%I64x", &val);
  585. hwndParent = (HWND)val;
  586. }
  587. #else
  588. hwndParent = (HWND)strtoul( apszArgs[SETUPARG_HWND], NULL, 16);
  589. #endif
  590. if ( !IsWindow( hwndParent ) )
  591. {
  592. nError = ERR_HWNDPARAM;
  593. hwndParent = GetActiveWindow(); // use active window as parent
  594. if (!IsWindow( hwndParent ) )
  595. {
  596. hwndParent = GetDesktopWindow();
  597. }
  598. }
  599. if ( CreateWSTR( &dlgParam.pszService, apszArgs[SETUPARG_SERVICE] ) &&
  600. CreateWSTR( &dlgParam.pszDisplayName, apszArgs[SETUPARG_NAME] ) &&
  601. CreateWSTR( &dlgParam.pszFamilyDisplayName, apszArgs[SETUPARG_FAMILYNAME] ) )
  602. {
  603. if ( bCertRequired )
  604. {
  605. nError = ServiceSecuritySet( dlgParam.pszComputer, dlgParam.pszDisplayName );
  606. }
  607. else
  608. {
  609. nError = ERR_NONE;
  610. }
  611. if ( ERR_NONE == nError )
  612. {
  613. if (0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szSETUP_PERSEAT ))
  614. {
  615. // use the licensing help context as the main help context
  616. dlgParam.dwHelpContext = LICCPA_HELPCONTEXTLICENSING;
  617. //
  618. // Check if this is a special version of liccpa.
  619. //
  620. if (gSpecVerInfo.idsSpecVerWarning)
  621. {
  622. dlgParam.fNoExit = TRUE;
  623. nError = SpecialSetupDialog( hwndParent,
  624. dlgParam );
  625. }
  626. else
  627. {
  628. nError = PerSeatSetupDialog( hwndParent,
  629. dlgParam );
  630. }
  631. }
  632. else
  633. {
  634. if (0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szSETUP_NORMALNOEXIT ))
  635. {
  636. dlgParam.fNoExit = TRUE;
  637. }
  638. //
  639. // Check if this is a special version of liccpa.
  640. //
  641. if (gSpecVerInfo.idsSpecVerWarning)
  642. {
  643. nError = SpecialSetupDialog( hwndParent,
  644. dlgParam );
  645. }
  646. else
  647. {
  648. nError = SetupDialog( hwndParent, dlgParam );
  649. }
  650. }
  651. }
  652. else
  653. {
  654. nError = ERR_SERVICEPARAM;
  655. }
  656. }
  657. if (fCustomHelp)
  658. {
  659. GlobalFree( (HGLOBAL)dlgParam.pszHelpFile );
  660. }
  661. GlobalFree( (HGLOBAL)dlgParam.pszService );
  662. GlobalFree( (HGLOBAL)dlgParam.pszDisplayName );
  663. GlobalFree( (HGLOBAL)dlgParam.pszFamilyDisplayName );
  664. }
  665. else
  666. {
  667. nError = ERR_NUMPARAMS;
  668. }
  669. } while (FALSE);
  670. return( nError );
  671. }
  672. //-------------------------------------------------------------------
  673. //
  674. // Function: UnattendedSetup
  675. //
  676. // Summary;
  677. // This will save the passed values in the registry, keeping all
  678. // licensing rules in effect and returning errorr/raising dialogs if
  679. // errors occur.
  680. //
  681. // Arguments
  682. // nArgs [in] - The number of arguments in the apszArgs array
  683. // apszArgs[] [in] - The argumnents passed in,
  684. // [0] szRoutine - The type of setup to run (Unattended)
  685. // [1] szService - The Reg Key name of the service
  686. // [2] szFamilyDisplayName - The family display name of the service
  687. // [3] szDisplayName - The display name of the service
  688. // [4] szMode - The string that defines the mode (PerSeat | PerServer)
  689. // [5] szUsers - The DWORD to use as the count of users in PerServer mode
  690. //
  691. // Return:
  692. // 0 - sucessfull
  693. // ERR_HELPPARAMS
  694. // ERR_HWNDPARAM
  695. // ERR_SERVICEPARAM
  696. // ERR_NUMPARAMS
  697. // ERR_CLASSREGFAILED
  698. // ERR_INVALIDROUTINE
  699. // ERR_INVALIDMODE
  700. //
  701. // Notes:
  702. //
  703. // History:
  704. // Dec-09-94 MikeMi Created
  705. //
  706. //-------------------------------------------------------------------
  707. const int UNSETUPARG_SETUP = 0;
  708. const int UNSETUPARG_SERVICE = 1;
  709. const int UNSETUPARG_FAMILYNAME = 2;
  710. const int UNSETUPARG_NAME = 3;
  711. const int UNSETUPARG_MODE = 4;
  712. const int UNSETUPARG_USERS = 5;
  713. const int UNSETUPARG_CERTREQUIRED = 6;
  714. const int UNSETUPARG_NARGSREQUIRED = 6;
  715. const int UNSETUPARG_NARGSWOPTIONAL = 7;
  716. int UnattendedSetup( DWORD nArgs, LPSTR apszArgs[] )
  717. {
  718. int nError = 0;
  719. LPWSTR pszService;
  720. LPWSTR pszDisplayName;
  721. LPWSTR pszFamilyDisplayName;
  722. LICENSE_MODE lmMode;
  723. DWORD dwUsers;
  724. do
  725. {
  726. if ( (nArgs == UNSETUPARG_NARGSREQUIRED) || (nArgs == UNSETUPARG_NARGSWOPTIONAL) )
  727. {
  728. if ( CreateWSTR( &pszService, apszArgs[UNSETUPARG_SERVICE] ) &&
  729. CreateWSTR( &pszDisplayName, apszArgs[UNSETUPARG_NAME] ) &&
  730. CreateWSTR( &pszFamilyDisplayName, apszArgs[UNSETUPARG_FAMILYNAME] ) )
  731. {
  732. nError = ERR_NONE;
  733. if ( nArgs > UNSETUPARG_CERTREQUIRED )
  734. {
  735. // cert required / not required given
  736. if ( !lstrcmpiA( szSETUP_CERTREQUIRED, apszArgs[UNSETUPARG_CERTREQUIRED] ) )
  737. {
  738. nError = ServiceSecuritySet( NULL, pszDisplayName );
  739. }
  740. else if ( lstrcmpiA( szSETUP_CERTNOTREQUIRED, apszArgs[UNSETUPARG_CERTREQUIRED] ) )
  741. {
  742. // unrecognized argument for cert required/not required
  743. nError = ERR_CERTREQPARAM;
  744. }
  745. }
  746. if ( ERR_NONE == nError )
  747. {
  748. //
  749. // Check if this is a special version of liccpa.
  750. //
  751. if (gSpecVerInfo.idsSpecVerWarning)
  752. {
  753. lmMode = gSpecVerInfo.lmSpecialMode;
  754. dwUsers = gSpecVerInfo.dwSpecialUsers;
  755. }
  756. else
  757. {
  758. if (0 == lstrcmpiA( apszArgs[UNSETUPARG_MODE],
  759. szUNATTENDED_PERSERVER ))
  760. {
  761. lmMode = LICMODE_PERSERVER;
  762. }
  763. else if (0 == lstrcmpiA( apszArgs[UNSETUPARG_MODE],
  764. szUNATTENDED_PERSEAT ))
  765. {
  766. lmMode = LICMODE_PERSEAT;
  767. }
  768. else
  769. {
  770. nError = ERR_INVALIDMODE;
  771. break;
  772. }
  773. dwUsers = (DWORD)strtoul( apszArgs[UNSETUPARG_USERS],
  774. NULL, 0);
  775. }
  776. nError = UpdateReg( NULL,
  777. pszService,
  778. pszFamilyDisplayName,
  779. pszDisplayName,
  780. lmMode,
  781. dwUsers );
  782. }
  783. GlobalFree( (HGLOBAL)pszService );
  784. GlobalFree( (HGLOBAL)pszDisplayName );
  785. GlobalFree( (HGLOBAL)pszFamilyDisplayName );
  786. }
  787. else
  788. {
  789. nError = ERR_SERVICEPARAM;
  790. }
  791. }
  792. else
  793. {
  794. nError = ERR_NUMPARAMS;
  795. }
  796. } while (FALSE);
  797. return( nError );
  798. }
  799. //-------------------------------------------------------------------
  800. //
  801. // Function: RemoteSetup
  802. //
  803. // Summary;
  804. // Run normal setup, Perseat Setup, normal setup without exit remotely
  805. //
  806. // Arguments
  807. // nArgs [in] - The number of arguments in the apszArgs array
  808. // If this value is 6, help button will call common help
  809. // If this value is 10, help button will call the passed help
  810. // apszArgs[] [in] - The argumnents passed in,
  811. // [0] szRoutine - The type of setup to run
  812. // [1] szComputer - the name of the computer to setup on (\\name)
  813. // [2] szHwnd - The parent Window handle, in HEX!
  814. // [3] szService - The Reg Key name of the service
  815. // [4] szFamilyDisplayName - The family display name of the service
  816. // [5] szDisplayName - The display name of the service
  817. // [6] szHelpFile - The complete path and name to help file
  818. // leave as an empty string to remove help buttons
  819. // [7] szHelpContext - the DWORD to use as the main help context
  820. // [8] szHCPerSeat - the DWORD to use as the PerSeat Help context
  821. // [9] szHCPerServer - the DWORD to use as the PerServer help context
  822. //
  823. // Return:
  824. // 0 - sucessfull
  825. // ERR_PERMISSIONDENIED
  826. // ERR_HELPPARAMS
  827. // ERR_HWNDPARAM
  828. // ERR_SERVICEPARAM
  829. // ERR_NUMPARAMS
  830. // ERR_CLASSREGFAILED
  831. // ERR_INVALIDROUTINE
  832. // ERR_INVALIDMODE
  833. //
  834. // Notes:
  835. //
  836. // History:
  837. // Apr-26-95 MikeMi Created
  838. //
  839. //-------------------------------------------------------------------
  840. const int REMSETUPARG_SETUP = 0;
  841. const int REMSETUPARG_COMPUTER = 1;
  842. const int REMSETUPARG_HWND = 2;
  843. const int REMSETUPARG_SERVICE = 3;
  844. const int REMSETUPARG_FAMILYNAME = 4;
  845. const int REMSETUPARG_NAME = 5;
  846. const int REMSETUPARG_HELPFILE = 6;
  847. const int REMSETUPARG_HELPCONTEXT = 7;
  848. const int REMSETUPARG_HCPERSEAT = 8;
  849. const int REMSETUPARG_HCPERSERVER = 9;
  850. const int REMSETUPARG_CERTREQUIRED = 10;
  851. const int REMSETUPARG_WOOPTIONAL = 6; // count of args without optional
  852. const int REMSETUPARG_WOPTIONAL = 10; // count of args with optional
  853. const int REMSETUPARG_WOPTIONALEX = 11; // count of args with optional + certrequired
  854. INT_PTR RemoteSetup( DWORD nArgs, LPSTR apszArgs[] )
  855. {
  856. SETUPDLGPARAM dlgParam;
  857. INT_PTR nError = 0;
  858. HWND hwndParent = NULL;
  859. BOOL fCustomHelp = FALSE;
  860. BOOL bCertRequired = FALSE;
  861. dlgParam.pszHelpFile = (LPWSTR)LICCPA_HELPFILE;
  862. dlgParam.dwHelpContext = LICCPA_HELPCONTEXTMAINSETUP;
  863. dlgParam.dwHCPerServer = LICCPA_HELPCONTEXTPERSERVER;
  864. dlgParam.dwHCPerSeat = LICCPA_HELPCONTEXTPERSEAT;
  865. dlgParam.pszService = NULL;
  866. dlgParam.fNoExit = FALSE;
  867. do
  868. {
  869. nError = ERR_NONE;
  870. if ((nArgs == REMSETUPARG_WOPTIONAL) || (nArgs == REMSETUPARG_WOOPTIONAL) || (nArgs == REMSETUPARG_WOPTIONALEX))
  871. {
  872. if (nArgs > REMSETUPARG_WOOPTIONAL)
  873. {
  874. if ( ( NULL != apszArgs[REMSETUPARG_HELPFILE] ) && lstrcmpiA( apszArgs[REMSETUPARG_HELPFILE], szSETUP_DEFAULTHELP ) )
  875. {
  876. LPWSTR pszHelpFile;
  877. if ( CreateWSTR( &pszHelpFile, apszArgs[REMSETUPARG_HELPFILE] ) )
  878. {
  879. if (0 == lstrlen( pszHelpFile ))
  880. {
  881. GlobalFree( (HGLOBAL)pszHelpFile );
  882. dlgParam.pszHelpFile = NULL; // should remove help buttons
  883. }
  884. else
  885. {
  886. fCustomHelp = TRUE;
  887. dlgParam.pszHelpFile = pszHelpFile;
  888. }
  889. }
  890. else
  891. {
  892. nError = ERR_HELPPARAMS;
  893. break;
  894. }
  895. dlgParam.dwHelpContext = (DWORD)strtoul( apszArgs[REMSETUPARG_HELPCONTEXT], NULL, 0);
  896. dlgParam.dwHCPerSeat = (DWORD)strtoul( apszArgs[REMSETUPARG_HCPERSEAT], NULL, 0);
  897. dlgParam.dwHCPerServer = (DWORD)strtoul( apszArgs[REMSETUPARG_HCPERSERVER], NULL, 0);
  898. }
  899. if ( nArgs > REMSETUPARG_CERTREQUIRED )
  900. {
  901. // cert required / not required given
  902. if ( !lstrcmpiA( szSETUP_CERTREQUIRED, apszArgs[REMSETUPARG_CERTREQUIRED] ) )
  903. {
  904. bCertRequired = TRUE;
  905. }
  906. else if ( lstrcmpiA( szSETUP_CERTNOTREQUIRED, apszArgs[REMSETUPARG_CERTREQUIRED] ) )
  907. {
  908. // unrecognized argument for cert required/not required
  909. nError = ERR_CERTREQPARAM;
  910. break;
  911. }
  912. }
  913. }
  914. // hwnd is in hex!
  915. #ifdef _WIN64
  916. {
  917. _int64 val = 0;
  918. sscanf(apszArgs[REMSETUPARG_HWND], "%I64x", &val);
  919. hwndParent = (HWND)val;
  920. }
  921. #else
  922. hwndParent = (HWND)strtoul( apszArgs[REMSETUPARG_HWND], NULL, 16);
  923. #endif
  924. if ( !IsWindow( hwndParent ) )
  925. {
  926. nError = ERR_HWNDPARAM;
  927. hwndParent = GetActiveWindow(); // use active window as parent
  928. if (!IsWindow( hwndParent ) )
  929. {
  930. hwndParent = GetDesktopWindow();
  931. }
  932. }
  933. if ( CreateWSTR( &dlgParam.pszService, apszArgs[REMSETUPARG_SERVICE] ) &&
  934. CreateWSTR( &dlgParam.pszDisplayName, apszArgs[REMSETUPARG_NAME] ) &&
  935. CreateWSTR( &dlgParam.pszComputer, apszArgs[REMSETUPARG_COMPUTER] ) &&
  936. CreateWSTR( &dlgParam.pszFamilyDisplayName, apszArgs[REMSETUPARG_FAMILYNAME] ) )
  937. {
  938. if ( bCertRequired )
  939. {
  940. nError = ServiceSecuritySet( dlgParam.pszComputer, dlgParam.pszDisplayName );
  941. }
  942. else
  943. {
  944. nError = ERR_NONE;
  945. }
  946. if ( ERR_NONE == nError )
  947. {
  948. if (0 == lstrcmpiA( apszArgs[REMSETUPARG_SETUP], szREMOTESETUP_PERSEAT ))
  949. {
  950. // use the licensing help context as the main help context
  951. dlgParam.dwHelpContext = LICCPA_HELPCONTEXTLICENSING;
  952. //
  953. // Check if this is a special version of liccpa.
  954. //
  955. if (gSpecVerInfo.idsSpecVerWarning)
  956. {
  957. dlgParam.fNoExit = TRUE;
  958. nError = SpecialSetupDialog( hwndParent,
  959. dlgParam );
  960. }
  961. else
  962. {
  963. nError = PerSeatSetupDialog( hwndParent,
  964. dlgParam );
  965. }
  966. }
  967. else
  968. {
  969. if (0 == lstrcmpiA( apszArgs[REMSETUPARG_SETUP], szREMOTESETUP_NORMALNOEXIT ))
  970. {
  971. dlgParam.fNoExit = TRUE;
  972. }
  973. //
  974. // Check if this is a special version of liccpa.
  975. //
  976. if (gSpecVerInfo.idsSpecVerWarning)
  977. {
  978. nError = SpecialSetupDialog( hwndParent,
  979. dlgParam );
  980. }
  981. else
  982. {
  983. nError = SetupDialog( hwndParent, dlgParam );
  984. }
  985. }
  986. }
  987. }
  988. else
  989. {
  990. nError = ERR_SERVICEPARAM;
  991. }
  992. if (fCustomHelp)
  993. {
  994. GlobalFree( (HGLOBAL)dlgParam.pszHelpFile );
  995. }
  996. GlobalFree( (HGLOBAL)dlgParam.pszService );
  997. GlobalFree( (HGLOBAL)dlgParam.pszDisplayName );
  998. GlobalFree( (HGLOBAL)dlgParam.pszFamilyDisplayName );
  999. GlobalFree( (HGLOBAL)dlgParam.pszComputer );
  1000. }
  1001. else
  1002. {
  1003. nError = ERR_NUMPARAMS;
  1004. }
  1005. } while (FALSE);
  1006. return( nError );
  1007. }
  1008. //-------------------------------------------------------------------
  1009. //
  1010. // Function: RemoteUnattendedSetup
  1011. //
  1012. // Summary;
  1013. // This will save the passed values in the registry, keeping all
  1014. // licensing rules in effect and returning errorr/raising dialogs if
  1015. // errors occur. This is done remotely on the computer specified.
  1016. //
  1017. // Arguments
  1018. // nArgs [in] - The number of arguments in the apszArgs array
  1019. // apszArgs[] [in] - The argumnents passed in,
  1020. // [0] szRoutine - The type of setup to run (Unattended)
  1021. // [1] szComputer - the name of the computer to setup on (\\name)
  1022. // [2] szService - The Reg Key name of the service
  1023. // [3] szFamilyDisplayName - The family display name of the service
  1024. // [4] szDisplayName - The display name of the service
  1025. // [5] szMode - The string that defines the mode (PerSeat | PerServer)
  1026. // [6] szUsers - The DWORD to use as the count of users in PerServer mode
  1027. //
  1028. // Return:
  1029. // 0 - sucessfull
  1030. // ERR_PERMISSIONDENIED
  1031. // ERR_HELPPARAMS
  1032. // ERR_HWNDPARAM
  1033. // ERR_SERVICEPARAM
  1034. // ERR_USERSPARAM
  1035. // ERR_NUMPARAMS
  1036. // ERR_CLASSREGFAILED
  1037. // ERR_INVALIDROUTINE
  1038. // ERR_INVALIDMODE
  1039. //
  1040. // Notes:
  1041. //
  1042. // History:
  1043. // Apr-26-95 MikeMi Created
  1044. //
  1045. //-------------------------------------------------------------------
  1046. const int REMUNSETUPARG_SETUP = 0;
  1047. const int REMUNSETUPARG_COMPUTER = 1;
  1048. const int REMUNSETUPARG_SERVICE = 2;
  1049. const int REMUNSETUPARG_FAMILYNAME = 3;
  1050. const int REMUNSETUPARG_NAME = 4;
  1051. const int REMUNSETUPARG_MODE = 5;
  1052. const int REMUNSETUPARG_USERS = 6;
  1053. const int REMUNSETUPARG_CERTREQUIRED = 7;
  1054. const int REMUNSETUPARG_NARGSREQUIRED = 7;
  1055. const int REMUNSETUPARG_NARGSWOPTIONAL = 8;
  1056. int RemoteUnattendedSetup( DWORD nArgs, LPSTR apszArgs[] )
  1057. {
  1058. int nError = 0;
  1059. LPWSTR pszService;
  1060. LPWSTR pszDisplayName;
  1061. LPWSTR pszFamilyDisplayName;
  1062. LPWSTR pszComputerName;
  1063. LICENSE_MODE lmMode;
  1064. DWORD dwUsers;
  1065. do
  1066. {
  1067. if ( (nArgs == REMUNSETUPARG_NARGSREQUIRED) || (nArgs == REMUNSETUPARG_NARGSWOPTIONAL) )
  1068. {
  1069. if ( CreateWSTR( &pszService, apszArgs[REMUNSETUPARG_SERVICE] ) &&
  1070. CreateWSTR( &pszDisplayName, apszArgs[REMUNSETUPARG_NAME] ) &&
  1071. CreateWSTR( &pszFamilyDisplayName, apszArgs[REMUNSETUPARG_FAMILYNAME] ) &&
  1072. CreateWSTR( &pszComputerName, apszArgs[REMUNSETUPARG_COMPUTER] ) )
  1073. {
  1074. nError = ERR_NONE;
  1075. if ( nArgs > REMUNSETUPARG_CERTREQUIRED )
  1076. {
  1077. // cert required / not required given
  1078. if ( !lstrcmpiA( szSETUP_CERTREQUIRED, apszArgs[REMUNSETUPARG_CERTREQUIRED] ) )
  1079. {
  1080. nError = ServiceSecuritySet( pszComputerName, pszDisplayName );
  1081. }
  1082. else if ( lstrcmpiA( szSETUP_CERTNOTREQUIRED, apszArgs[REMUNSETUPARG_CERTREQUIRED] ) )
  1083. {
  1084. // unrecognized argument for cert required/not required
  1085. nError = ERR_CERTREQPARAM;
  1086. }
  1087. }
  1088. if ( ERR_NONE == nError )
  1089. {
  1090. //
  1091. // Check if this is a special version of liccpa.
  1092. //
  1093. if (gSpecVerInfo.idsSpecVerWarning)
  1094. {
  1095. lmMode = gSpecVerInfo.lmSpecialMode;
  1096. dwUsers = gSpecVerInfo.dwSpecialUsers;
  1097. }
  1098. else
  1099. {
  1100. if (0 == lstrcmpiA( apszArgs[REMUNSETUPARG_MODE],
  1101. szUNATTENDED_PERSERVER ))
  1102. {
  1103. lmMode = LICMODE_PERSERVER;
  1104. }
  1105. else if (0 == lstrcmpiA( apszArgs[REMUNSETUPARG_MODE],
  1106. szUNATTENDED_PERSEAT ))
  1107. {
  1108. lmMode = LICMODE_PERSEAT;
  1109. }
  1110. else
  1111. {
  1112. nError = ERR_INVALIDMODE;
  1113. break;
  1114. }
  1115. dwUsers = (DWORD)strtoul(
  1116. apszArgs[REMUNSETUPARG_USERS],
  1117. NULL, 0);
  1118. }
  1119. nError = UpdateReg( pszComputerName,
  1120. pszService,
  1121. pszFamilyDisplayName,
  1122. pszDisplayName,
  1123. lmMode,
  1124. dwUsers );
  1125. }
  1126. if(pszService != NULL)
  1127. {
  1128. GlobalFree( (HGLOBAL)pszService );
  1129. }
  1130. if(pszDisplayName != NULL)
  1131. {
  1132. GlobalFree( (HGLOBAL)pszDisplayName );
  1133. }
  1134. if(pszFamilyDisplayName != NULL)
  1135. {
  1136. GlobalFree( (HGLOBAL)pszFamilyDisplayName );
  1137. }
  1138. if(pszComputerName != NULL)
  1139. {
  1140. GlobalFree( (HGLOBAL)pszComputerName );
  1141. }
  1142. }
  1143. else
  1144. {
  1145. nError = ERR_SERVICEPARAM;
  1146. }
  1147. }
  1148. else
  1149. {
  1150. nError = ERR_NUMPARAMS;
  1151. }
  1152. } while (FALSE);
  1153. return( nError );
  1154. }
  1155. #pragma warning (pop) //4127
  1156. //-------------------------------------------------------------------
  1157. //
  1158. // Function: CPlSetup
  1159. //
  1160. // Summary;
  1161. // Dll entry point for License Mode Setup, to be used from Setup
  1162. // programs.
  1163. //
  1164. // Arguments
  1165. // nArgs [in] - The number of arguments in the apszArgs array
  1166. // apszArgs[] [in] - The argumnents passed in,
  1167. // [0] szRoutine - The type of setup to run
  1168. // FullSetup | RemoteFullSetup |
  1169. // PerSeatSetup | RemotePerSeatSetup |
  1170. // Unattended | RemoteUnattended |
  1171. // FullSetupNoexit | RemoteFullSetupNoexit
  1172. // ppszResult [out]- The result string
  1173. //
  1174. // Return:
  1175. //
  1176. // Notes:
  1177. //
  1178. // History:
  1179. // Nov-17-94 MikeMi Created
  1180. // Apr-26-95 MikeMi Added remoting routines
  1181. //
  1182. //-------------------------------------------------------------------
  1183. BOOL APIENTRY CPlSetup( DWORD nArgs, LPSTR apszArgs[], LPSTR *ppszResult )
  1184. {
  1185. INT_PTR nError = 0;
  1186. BOOL frt = TRUE;
  1187. //
  1188. // Initialize global special version information is this liccpa
  1189. // is a special version (eg: restricted SAM, NFR, etc).
  1190. //
  1191. InitSpecialVersionInfo();
  1192. if ((0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szSETUP_PERSEAT )) ||
  1193. (0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szSETUP_NORMAL )) ||
  1194. (0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szSETUP_NORMALNOEXIT )) )
  1195. {
  1196. nError = Setup( nArgs, apszArgs );
  1197. }
  1198. else if (0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szSETUP_UNATTENDED ))
  1199. {
  1200. nError = UnattendedSetup( nArgs, apszArgs );
  1201. }
  1202. else if ((0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szREMOTESETUP_PERSEAT )) ||
  1203. (0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szREMOTESETUP_NORMAL )) ||
  1204. (0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szREMOTESETUP_NORMALNOEXIT )) )
  1205. {
  1206. nError = RemoteSetup( nArgs, apszArgs );
  1207. }
  1208. else if (0 == lstrcmpiA( apszArgs[SETUPARG_SETUP], szREMOTESETUP_UNATTENDED ))
  1209. {
  1210. nError = RemoteUnattendedSetup( nArgs, apszArgs );
  1211. }
  1212. else
  1213. {
  1214. nError = ERR_INVALIDROUTINE;
  1215. }
  1216. // prepare error for return
  1217. switch (nError)
  1218. {
  1219. case 0:
  1220. *ppszResult = szSETUP_EXIT;
  1221. break;
  1222. case ERR_NONE:
  1223. *ppszResult = szSETUP_OK;
  1224. break;
  1225. case ERR_PERMISSIONDENIED:
  1226. frt = FALSE;
  1227. *ppszResult = szSETUP_SECURITY;
  1228. break;
  1229. case ERR_NOREMOTESERVER:
  1230. frt = FALSE;
  1231. *ppszResult = szSETUP_NOREMOTE;
  1232. break;
  1233. case ERR_DOWNLEVEL:
  1234. frt = FALSE;
  1235. *ppszResult = szSETUP_DOWNLEVEL;
  1236. break;
  1237. default:
  1238. *ppszResult = szSETUP_ERROR;
  1239. frt = FALSE;
  1240. break;
  1241. }
  1242. return( frt );
  1243. }