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.

1497 lines
27 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /*++
  4. Copyright (c) 1991 Microsoft Corporation
  5. Module Name:
  6. setupdll.c
  7. Abstract:
  8. This file continas the entrypoints for the Win32 Setup support DLL
  9. and common subroutines.
  10. Author:
  11. Ted Miller (tedm) July 1991
  12. --*/
  13. #define RETURN_BUFFER_SIZE 1024
  14. typedef DWORD (APIENTRY *PFWNETPROC)();
  15. CHAR ReturnTextBuffer[ RETURN_BUFFER_SIZE ];
  16. BOOL
  17. FForceDeleteFile(
  18. LPSTR szPath
  19. );
  20. #ifdef CONTIG
  21. // arg0 = drive (only first letter is signifiacnt)
  22. // arg1 = file
  23. BOOL
  24. MakeFileContiguous(
  25. IN DWORD cArgs,
  26. IN LPSTR Args[],
  27. OUT LPSTR *TextOut
  28. )
  29. {
  30. char ActualDrive[4];
  31. char ActualFile[13];
  32. *TextOut = ReturnTextBuffer;
  33. if(cArgs != 2) {
  34. SetErrorText(IDS_ERROR_BADARGS);
  35. return(FALSE);
  36. }
  37. ActualDrive[0] = *Args[0];
  38. ActualDrive[1] = ':';
  39. ActualDrive[2] = '\\';
  40. ActualDrive[3] = '\0';
  41. memset(ActualFile,0,13);
  42. strncpy(ActualFile,Args[1],12);
  43. *ReturnTextBuffer = '\0';
  44. return(MakeContigWorker(ActualDrive,ActualFile));
  45. }
  46. #endif
  47. #if 0
  48. // arg0 = drive -- must be 'x:\'
  49. // arg1 = filesystem ("FAT" or "HPFS")
  50. // arg2 = file containing boot code
  51. // arg3 = file for saving current boot sector
  52. BOOL
  53. LayBootCode(
  54. IN DWORD cArgs,
  55. IN LPSTR Args[],
  56. OUT LPSTR *TextOut
  57. )
  58. {
  59. *TextOut = ReturnTextBuffer;
  60. if(cArgs != 4) {
  61. SetErrorText(IDS_ERROR_BADARGS);
  62. return(FALSE);
  63. }
  64. *ReturnTextBuffer = '\0';
  65. return(LayBootCodeWorker(Args[0],Args[1],Args[2],Args[3]));
  66. }
  67. #endif
  68. // arg0 = Variable name ( OSLOADPARTITION, OSLOADFILENAME, OSLOADOPTIONS)
  69. // arg1 = Value to be set.
  70. BOOL
  71. SetNVRAMVar(
  72. IN DWORD cArgs,
  73. IN LPSTR Args[],
  74. OUT LPSTR *TextOut
  75. )
  76. {
  77. *TextOut = ReturnTextBuffer;
  78. if(cArgs != 2) {
  79. SetErrorText(IDS_ERROR_BADARGS);
  80. return(FALSE);
  81. }
  82. *ReturnTextBuffer = '\0';
  83. return(SetEnvironmentString(Args[0], Args[1]));
  84. }
  85. // arg0: fully qualified dos path
  86. BOOL
  87. DosPathToNtPath(
  88. IN DWORD cArgs,
  89. IN LPSTR Args[],
  90. OUT LPSTR *TextOut
  91. )
  92. {
  93. CHAR NtPath[MAX_PATH];
  94. *TextOut = ReturnTextBuffer;
  95. if(cArgs != 1) {
  96. SetErrorText(IDS_ERROR_BADARGS);
  97. return(FALSE);
  98. }
  99. if (!DosPathToNtPathWorker(*Args, NtPath)) {
  100. return (FALSE);
  101. }
  102. lstrcpy(ReturnTextBuffer, NtPath);
  103. return(TRUE);
  104. }
  105. // arg0: fully qualified dos path
  106. BOOL
  107. NtPathToDosPath(
  108. IN DWORD cArgs,
  109. IN LPSTR Args[],
  110. OUT LPSTR *TextOut
  111. )
  112. {
  113. CHAR DosPath[MAX_PATH];
  114. *TextOut = ReturnTextBuffer;
  115. if(cArgs != 1) {
  116. SetErrorText(IDS_ERROR_BADARGS);
  117. return(FALSE);
  118. }
  119. if (!NtPathToDosPathWorker(*Args, DosPath)) {
  120. return (FALSE);
  121. }
  122. lstrcpy(ReturnTextBuffer, DosPath);
  123. return(TRUE);
  124. }
  125. // arg0: fully qualified dos path
  126. BOOL
  127. DosPathToArcPath(
  128. IN DWORD cArgs,
  129. IN LPSTR Args[],
  130. OUT LPSTR *TextOut
  131. )
  132. {
  133. CHAR ArcPath[MAX_PATH];
  134. *TextOut = ReturnTextBuffer;
  135. if(cArgs != 1) {
  136. SetErrorText(IDS_ERROR_BADARGS);
  137. return(FALSE);
  138. }
  139. if (!DosPathToArcPathWorker(*Args, ArcPath)) {
  140. return (FALSE);
  141. }
  142. lstrcpy(ReturnTextBuffer, ArcPath);
  143. return(TRUE);
  144. }
  145. #if 0
  146. // Change scsi(x) to scsi() because there is only ever one miniport
  147. // driver loaded into ntldr.
  148. // arg0: arc path to change.
  149. BOOL
  150. FixArcPathForBootIni(
  151. IN DWORD cArgs,
  152. IN LPSTR Args[],
  153. OUT LPSTR *TextOut
  154. )
  155. {
  156. PCHAR p,q;
  157. *TextOut = ReturnTextBuffer;
  158. if(cArgs != 1) {
  159. SetErrorText(IDS_ERROR_BADARGS);
  160. return(FALSE);
  161. }
  162. lstrcpy(ReturnTextBuffer,Args[0]);
  163. _strlwr(ReturnTextBuffer);
  164. if(p = strstr(ReturnTextBuffer,"scsi(")) {
  165. p += 5; // p points to next char after scsi(
  166. if(q = strchr(p,')')) {
  167. memmove(p,q,lstrlen(q)+1);
  168. }
  169. }
  170. return(TRUE);
  171. }
  172. #endif
  173. // arg0 = fully qualified arc path
  174. BOOL
  175. ArcPathToDosPath(
  176. IN DWORD cArgs,
  177. IN LPSTR Args[],
  178. OUT LPSTR *TextOut
  179. )
  180. {
  181. CHAR DosName[MAX_PATH];
  182. *TextOut = ReturnTextBuffer;
  183. if(cArgs != 1) {
  184. SetErrorText(IDS_ERROR_BADARGS);
  185. return(FALSE);
  186. }
  187. if (!ArcPathToDosPathWorker(*Args, DosName)) {
  188. return (FALSE);
  189. }
  190. lstrcpy(ReturnTextBuffer, DosName);
  191. return(TRUE);
  192. }
  193. //
  194. // arg[0] Drive (X:)
  195. //
  196. BOOL
  197. CheckDriveExternal(
  198. IN DWORD cArgs,
  199. IN LPSTR Args[],
  200. OUT LPSTR *TextOut
  201. )
  202. {
  203. BOOL IsExternal;
  204. *TextOut = ReturnTextBuffer;
  205. if(cArgs != 1) {
  206. SetErrorText(IDS_ERROR_BADARGS);
  207. return(FALSE);
  208. }
  209. if (!IsDriveExternalScsi(*Args, &IsExternal)) {
  210. return(FALSE);
  211. }
  212. lstrcpy(ReturnTextBuffer, IsExternal ? "YES" : "NO");
  213. return(TRUE);
  214. }
  215. // arg0 = filename
  216. // arg2n+1 = original text string #n (n is 0-based)
  217. // arg2n+2 = substitute text string #n (n is 0-based)
  218. BOOL
  219. ConfigFileSubst(
  220. IN DWORD cArgs,
  221. IN LPSTR Args[],
  222. OUT LPSTR *TextOut
  223. )
  224. {
  225. *TextOut = ReturnTextBuffer;
  226. if((!(cArgs % 2)) || (cArgs == 1)) {
  227. SetErrorText(IDS_ERROR_BADARGS); // if cArgs is even
  228. return(FALSE);
  229. }
  230. *ReturnTextBuffer = '\0';
  231. return(ConfigFileSubstWorker(Args[0],(cArgs-1)/2,&Args[1]));
  232. }
  233. // arg0 = filename
  234. // arg2n+1 = original text string #n (n is 0-based)
  235. // arg2n+2 = substitute text string #n (n is 0-based)
  236. BOOL
  237. BinaryFileSubst(
  238. IN DWORD cArgs,
  239. IN LPSTR Args[],
  240. OUT LPSTR *TextOut
  241. )
  242. {
  243. *TextOut = ReturnTextBuffer;
  244. if((!(cArgs % 2)) || (cArgs == 1)) {
  245. SetErrorText(IDS_ERROR_BADARGS); // if cArgs is even
  246. return(FALSE);
  247. }
  248. *ReturnTextBuffer = '\0';
  249. return(BinaryFileSubstWorker(Args[0],(cArgs-1)/2,&Args[1]));
  250. }
  251. // arg0 = filename
  252. // argn = append text string #n (n >= 1)
  253. BOOL
  254. ConfigFileAppend(
  255. IN DWORD cArgs,
  256. IN LPSTR Args[],
  257. OUT LPSTR *TextOut
  258. )
  259. {
  260. *TextOut = ReturnTextBuffer;
  261. if(cArgs == 1) {
  262. SetErrorText(IDS_ERROR_BADARGS);
  263. return(FALSE);
  264. }
  265. *ReturnTextBuffer = '\0';
  266. return(ConfigFileAppendWorker(Args[0],cArgs-1,&Args[1]));
  267. }
  268. //
  269. // arg0 = filename
  270. //
  271. BOOL
  272. DelFile(
  273. IN DWORD cArgs,
  274. IN LPSTR Args[],
  275. OUT LPSTR *TextOut
  276. )
  277. {
  278. OFSTRUCT ReOpen;
  279. BOOL b;
  280. *TextOut = ReturnTextBuffer;
  281. if(cArgs != 1) {
  282. SetErrorText(IDS_ERROR_BADARGS);
  283. return(FALSE);
  284. }
  285. *ReturnTextBuffer = '\0';
  286. //
  287. // If file doesn't exist then return true
  288. //
  289. if ( OpenFile(Args[0],&ReOpen,OF_EXIST) == -1 ) {
  290. SetReturnText("SUCCESS");
  291. return( TRUE );
  292. }
  293. //
  294. // Try to delete the file or force delete the file
  295. //
  296. if(b = SetFileAttributes(Args[0],FILE_ATTRIBUTE_NORMAL)) {
  297. b = DeleteFile(Args[0]);
  298. }
  299. if(!b) {
  300. if(FForceDeleteFile(Args[0])) {
  301. b = DeleteFile(Args[0]);
  302. }
  303. }
  304. SetReturnText(b ? "SUCCESS" : "FAILED");
  305. return( TRUE );
  306. }
  307. //
  308. // arg0 = old filename
  309. // arg1 = new filename
  310. //
  311. BOOL
  312. RenFile(
  313. IN DWORD cArgs,
  314. IN LPSTR Args[],
  315. OUT LPSTR *TextOut
  316. )
  317. {
  318. *TextOut = ReturnTextBuffer;
  319. if(cArgs != 2) {
  320. SetErrorText(IDS_ERROR_BADARGS);
  321. return(FALSE);
  322. }
  323. *ReturnTextBuffer = '\0';
  324. return(MoveFile(Args[0],Args[1]));
  325. }
  326. //
  327. // arg0 = source filename
  328. // arg1 = destination filename
  329. //
  330. BOOL
  331. CopySingleFile(
  332. IN DWORD cArgs,
  333. IN LPSTR Args[],
  334. OUT LPSTR *TextOut
  335. )
  336. {
  337. BOOL bStatus;
  338. *TextOut = ReturnTextBuffer;
  339. if(cArgs != 2) {
  340. SetErrorText(IDS_ERROR_BADARGS);
  341. return(FALSE);
  342. }
  343. *ReturnTextBuffer = '\0';
  344. bStatus = CopyFile( Args[0], Args[1], FALSE );
  345. if (!bStatus) {
  346. SetErrorText(IDS_ERROR_COPYFILE);
  347. }
  348. return (bStatus);
  349. }
  350. //
  351. // arg0 = list
  352. //
  353. BOOL
  354. SumListItems(
  355. IN DWORD cArgs,
  356. IN LPSTR Args[],
  357. OUT LPSTR *TextOut
  358. )
  359. {
  360. LPSTR n,p;
  361. UINT Sum,Number;
  362. *TextOut = ReturnTextBuffer;
  363. if(cArgs != 1) {
  364. SetErrorText(IDS_ERROR_BADARGS);
  365. return(FALSE);
  366. }
  367. Sum = 0;
  368. p = Args[0];
  369. n = CharNext(p);
  370. while(n-p) { // else *p was 0
  371. if(n-p == 1) { // single byte char
  372. Number = 0;
  373. while((n-p == 1) && (*p >= '0') && (*p <= '9')) {
  374. Number = 10*Number + (UINT)(UCHAR)*p - (UINT)(UCHAR)'0';
  375. p = n;
  376. n = CharNext(p);
  377. }
  378. Sum += Number;
  379. }
  380. p = n;
  381. n = CharNext(p);
  382. }
  383. wsprintf(ReturnTextBuffer,"%d",Sum);
  384. return(TRUE);
  385. }
  386. // arg0 = YES for Reboot after Shutdown, NO for no Reboot.
  387. BOOL
  388. ShutdownSystem(
  389. IN DWORD cArgs,
  390. IN LPSTR Args[],
  391. OUT LPSTR *TextOut
  392. )
  393. {
  394. BOOL Reboot, Status;
  395. LONG Privilege = SE_SHUTDOWN_PRIVILEGE;
  396. TOKEN_PRIVILEGES PrevState;
  397. ULONG ReturnLength = sizeof( TOKEN_PRIVILEGES );
  398. *TextOut = ReturnTextBuffer;
  399. if(cArgs != 1) {
  400. SetErrorText(IDS_ERROR_BADARGS); // if reboot indication not given
  401. return(FALSE);
  402. }
  403. *ReturnTextBuffer = '\0';
  404. if (!lstrcmpi(Args[0], "YES"))
  405. Reboot = TRUE;
  406. else if (!lstrcmpi(Args[0], "NO"))
  407. Reboot = FALSE;
  408. else
  409. return(FALSE);
  410. //
  411. // Enable the shutdown privilege
  412. //
  413. if ( !AdjustPrivilege(
  414. Privilege,
  415. ENABLE_PRIVILEGE,
  416. &PrevState,
  417. &ReturnLength
  418. )
  419. ) {
  420. SetErrorText( IDS_ERROR_PRIVILEGE );
  421. return( FALSE );
  422. }
  423. Status = ShutdownSystemWorker(Reboot);
  424. RestorePrivilege( &PrevState );
  425. if( !Status ) {
  426. SetErrorText( IDS_ERROR_SHUTDOWN );
  427. }
  428. return( Status );
  429. }
  430. // arg0 = string to check
  431. BOOL
  432. WhiteSpaceCheck(
  433. IN DWORD cArgs,
  434. IN LPSTR Args[],
  435. OUT LPSTR *TextOut
  436. )
  437. {
  438. LPSTR p;
  439. BOOL WhiteSpace;
  440. *TextOut = ReturnTextBuffer;
  441. if(cArgs != 1) {
  442. SetErrorText(IDS_ERROR_BADARGS);
  443. return(FALSE);
  444. }
  445. for(WhiteSpace = FALSE, p = *Args; *p && !WhiteSpace; p++) {
  446. if(isspace((unsigned char)(*p))) {
  447. WhiteSpace = TRUE;
  448. }
  449. }
  450. lstrcpy(ReturnTextBuffer,WhiteSpace ? "YES" : "NO");
  451. return(TRUE);
  452. }
  453. // arg0 = string to check
  454. BOOL
  455. NetNameCheck(
  456. IN DWORD cArgs,
  457. IN LPSTR Args[],
  458. OUT LPSTR *TextOut
  459. )
  460. {
  461. DWORD len = lstrlen(Args[0]);
  462. #define CTRL_CHARS_0 TEXT( "\001\002\003\004\005\006\007")
  463. #define CTRL_CHARS_1 TEXT("\010\011\012\013\014\015\016\017")
  464. #define CTRL_CHARS_2 TEXT("\020\021\022\023\024\025\026\027")
  465. #define CTRL_CHARS_3 TEXT("\030\031\032\033\034\035\036\037")
  466. #define CTRL_CHARS_STR CTRL_CHARS_0 CTRL_CHARS_1 CTRL_CHARS_2 CTRL_CHARS_3
  467. #define ILLEGAL_NAME_CHARS_STR TEXT("\"/\\[]:|<>+=;,?*") CTRL_CHARS_STR
  468. *TextOut = ReturnTextBuffer;
  469. if(cArgs != 1) {
  470. SetErrorText(IDS_ERROR_BADARGS);
  471. return(FALSE);
  472. }
  473. //
  474. // Leading/trailing spaces are invalid.
  475. //
  476. lstrcpy(ReturnTextBuffer,
  477. ( (Args[0][0] != ' ')
  478. && (Args[0][len-1] != ' ')
  479. && (_mbscspn(Args[0],ILLEGAL_NAME_CHARS_STR) == _mbstrlen(Args[0]))
  480. )
  481. ? "YES"
  482. : "NO"
  483. );
  484. return(TRUE);
  485. }
  486. // arg0 = file to check for (may be a directory)
  487. BOOL
  488. CheckFileExistance(
  489. IN DWORD cArgs,
  490. IN LPSTR Args[],
  491. OUT LPSTR *TextOut
  492. )
  493. {
  494. DWORD d;
  495. *TextOut = ReturnTextBuffer;
  496. if(cArgs != 1) {
  497. SetErrorText(IDS_ERROR_BADARGS);
  498. return(FALSE);
  499. }
  500. d = GetFileAttributes(*Args);
  501. lstrcpy(ReturnTextBuffer,(d == (DWORD)(-1)) ? "NO" : "YES");
  502. return(TRUE);
  503. }
  504. // arg0 = config file to check. This returns if it is a DOS config
  505. // or not.
  506. BOOL
  507. CheckConfigType(
  508. IN DWORD cArgs,
  509. IN LPSTR Args[],
  510. OUT LPSTR *TextOut
  511. )
  512. {
  513. *TextOut = ReturnTextBuffer;
  514. if(cArgs != 1) {
  515. SetErrorText(IDS_ERROR_BADARGS);
  516. return(FALSE);
  517. }
  518. lstrcpy(ReturnTextBuffer, CheckConfigTypeWorker( Args[0] ) ? "DOS" : "OS2");
  519. return ( TRUE );
  520. }
  521. //
  522. // Create config.nt [and possibly autoexec.nt] for the Dos subsystem
  523. //
  524. // Args[0]: Add on block for config.nt
  525. // Args[1]: Add on block for autoexec.nt
  526. BOOL
  527. VdmFixup(
  528. IN DWORD cArgs,
  529. IN LPSTR Args[],
  530. OUT LPSTR *TextOut
  531. )
  532. {
  533. *TextOut = ReturnTextBuffer;
  534. if(cArgs != 2) {
  535. SetErrorText(IDS_ERROR_BADARGS);
  536. return(FALSE);
  537. }
  538. *ReturnTextBuffer = '\0';
  539. return( VdmFixupWorker( Args[0], Args[1]) );
  540. }
  541. // arg0 = Remote name
  542. // arg1 = Password
  543. // arg2 = Local Name
  544. BOOL
  545. AddNetConnection(
  546. IN DWORD cArgs,
  547. IN LPSTR Args[],
  548. OUT LPSTR *TextOut
  549. )
  550. {
  551. SZ szPassword = NULL;
  552. *TextOut = ReturnTextBuffer;
  553. if(cArgs < 2) {
  554. SetErrorText(IDS_ERROR_BADARGS);
  555. return(FALSE);
  556. }
  557. if(cArgs >= 3) {
  558. szPassword = Args[2];
  559. }
  560. return ( AddNetConnectionWorker( Args[0], szPassword, Args[1] ) );
  561. }
  562. //
  563. // Arg[0]: Local Name
  564. // Arg[1]: Force closure -- "TRUE" | "FALSE"
  565. //
  566. BOOL
  567. DeleteNetConnection(
  568. IN DWORD cArgs,
  569. IN LPSTR Args[],
  570. OUT LPSTR *TextOut
  571. )
  572. {
  573. *TextOut = ReturnTextBuffer;
  574. if(cArgs != 2) {
  575. SetErrorText(IDS_ERROR_BADARGS);
  576. return(FALSE);
  577. }
  578. DeleteNetConnectionWorker( Args[0], Args[1] );
  579. return( TRUE );
  580. }
  581. //
  582. // Args[0]: Printer Model (eg QMS ..)
  583. // Args[1]: Printer Environment (eg w32x86)
  584. // Args[2]: Printer Driver (eg pscript.dll)
  585. // Args[3]: Printer Datafile (eg QMS810.PPD)
  586. // Args[4]: Printer Configfile (eg PSCRPTUI.DLL)
  587. //
  588. BOOL
  589. SetupAddPrinterDriver(
  590. IN DWORD cArgs,
  591. IN LPSTR Args[],
  592. OUT LPSTR *TextOut
  593. )
  594. {
  595. SZ Server = NULL;
  596. *TextOut = ReturnTextBuffer;
  597. if(cArgs < 5) {
  598. SetErrorText(IDS_ERROR_BADARGS);
  599. return(FALSE);
  600. }
  601. *ReturnTextBuffer = '\0';
  602. if( cArgs > 5 && (*(Args[5]) != '\0')) {
  603. Server = Args[5];
  604. }
  605. return(
  606. AddPrinterDriverWorker(
  607. Args[0],
  608. Args[1],
  609. Args[2],
  610. Args[3],
  611. Args[4],
  612. Server
  613. ) );
  614. }
  615. //
  616. // Args[0]: Monitor Model (eg QMS ..)
  617. // Args[1]: Monitor Environment (eg w32x86)
  618. // Args[2]: Monitor DLL (eg pscript.dll)
  619. //
  620. BOOL
  621. SetupAddPrinterMonitor(
  622. IN DWORD cArgs,
  623. IN LPSTR Args[],
  624. OUT LPSTR *TextOut
  625. )
  626. {
  627. SZ Server = NULL;
  628. *TextOut = ReturnTextBuffer;
  629. if(cArgs < 3) {
  630. SetErrorText(IDS_ERROR_BADARGS);
  631. return(FALSE);
  632. }
  633. *ReturnTextBuffer = '\0';
  634. if( cArgs > 3 && (*(Args[3]) != '\0')) {
  635. Server = Args[3];
  636. }
  637. return(
  638. AddPrinterMonitorWorker(
  639. Args[0],
  640. Args[1],
  641. Args[2],
  642. Server
  643. ) );
  644. }
  645. // Args[0]: Printer Name (My Favorite Printer)
  646. // Args[1]: Printer Port (COM1..)
  647. // Args[2]: Printer Driver (e.g. HP LAserJet IIP)
  648. // Args[3]: Printer Description (e.g. HP LasetJet IIP on COM1:)
  649. // Args[4]: Printer Processor (WINPRINT)
  650. // Args[5]: Printer Attributes (QUEUEDDEFAULT..)
  651. BOOL
  652. SetupAddPrinter(
  653. IN DWORD cArgs,
  654. IN LPSTR Args[],
  655. OUT LPSTR *TextOut
  656. )
  657. {
  658. SZ Server = NULL;
  659. *TextOut = ReturnTextBuffer;
  660. if(cArgs < 6) {
  661. SetErrorText(IDS_ERROR_BADARGS);
  662. return(FALSE);
  663. }
  664. *ReturnTextBuffer = '\0';
  665. if( cArgs > 6 && (*(Args[6]) != '\0')) {
  666. Server = Args[6];
  667. }
  668. return(
  669. AddPrinterWorker(
  670. Args[0],
  671. Args[1],
  672. Args[2],
  673. Args[3],
  674. Args[4],
  675. (DWORD)atoi(Args[5]),
  676. Server
  677. ) );
  678. }
  679. BOOL
  680. AreCharsInString(
  681. IN DWORD cArgs,
  682. IN LPSTR Args[],
  683. OUT LPSTR *TextOut
  684. )
  685. {
  686. *TextOut = ReturnTextBuffer;
  687. if(cArgs != 2) {
  688. SetErrorText(IDS_ERROR_BADARGS);
  689. return(FALSE);
  690. }
  691. lstrcpy(ReturnTextBuffer,_mbspbrk(Args[0],Args[1]) ? "YES" : "NO");
  692. return(TRUE);
  693. }
  694. //
  695. // Security related library functions
  696. //
  697. //
  698. // 1. CheckPrivilegeExists <PrivilegeName>
  699. //
  700. BOOL
  701. CheckPrivilegeExists(
  702. IN DWORD cArgs,
  703. IN LPSTR Args[],
  704. OUT LPSTR *TextOut
  705. )
  706. {
  707. *TextOut = ReturnTextBuffer;
  708. if(cArgs != 1) {
  709. SetErrorText(IDS_ERROR_BADARGS);
  710. return(FALSE);
  711. }
  712. *ReturnTextBuffer = '\0';
  713. return( CheckPrivilegeExistsWorker( Args[0] ) );
  714. }
  715. //
  716. // 2. EnablePrivilege <Privilege> <ENABLE | DISABLE>
  717. //
  718. BOOL
  719. EnablePrivilege(
  720. IN DWORD cArgs,
  721. IN LPSTR Args[],
  722. OUT LPSTR *TextOut
  723. )
  724. {
  725. *TextOut = ReturnTextBuffer;
  726. if(cArgs != 2) {
  727. SetErrorText(IDS_ERROR_BADARGS);
  728. return(FALSE);
  729. }
  730. *ReturnTextBuffer = '\0';
  731. return( EnablePrivilegeWorker( Args[0], Args[1] ) );
  732. }
  733. //
  734. // 5. SetMyComputerName
  735. //
  736. BOOL
  737. SetMyComputerName(
  738. IN DWORD cArgs,
  739. IN LPSTR Args[],
  740. OUT LPSTR *TextOut
  741. )
  742. {
  743. *TextOut = ReturnTextBuffer;
  744. if(cArgs != 1) {
  745. SetErrorText(IDS_ERROR_BADARGS);
  746. return(FALSE);
  747. }
  748. *ReturnTextBuffer = '\0';
  749. return( SetMyComputerNameWorker( Args[0] ) );
  750. }
  751. //
  752. // DeleteAllConnections: Remove all automatically created UNC uses.
  753. //
  754. BOOL
  755. DeleteAllConnections(
  756. IN DWORD cArgs,
  757. IN LPSTR Args[],
  758. OUT LPSTR *TextOut
  759. )
  760. {
  761. *TextOut = ReturnTextBuffer;
  762. *ReturnTextBuffer = '\0';
  763. DeleteAllConnectionsWorker();
  764. return TRUE ;
  765. }
  766. //
  767. // Path related routines
  768. //
  769. BOOL
  770. CheckPathFullPathSpec(
  771. IN DWORD cArgs,
  772. IN LPSTR Args[],
  773. OUT LPSTR *TextOut
  774. )
  775. {
  776. BOOL IsFullPath = FALSE;
  777. DWORD Length;
  778. *TextOut = ReturnTextBuffer;
  779. if(cArgs != 1) {
  780. SetErrorText(IDS_ERROR_BADARGS);
  781. return(FALSE);
  782. }
  783. Length = lstrlen( Args[0] );
  784. if ( Length >= 2 && Args[0][1] == ':') {
  785. if( Length > 2 ) {
  786. if ( Args[0][2] == '\\' ) {
  787. IsFullPath = TRUE;
  788. }
  789. }
  790. else {
  791. IsFullPath = TRUE;
  792. }
  793. }
  794. lstrcpy(ReturnTextBuffer, IsFullPath ? "YES" : "NO");
  795. return(TRUE);
  796. }
  797. BOOL
  798. AppendBackSlash(
  799. IN DWORD cArgs,
  800. IN LPSTR Args[],
  801. OUT LPSTR *TextOut
  802. )
  803. {
  804. DWORD Length;
  805. *TextOut = ReturnTextBuffer;
  806. if(cArgs != 1) {
  807. SetErrorText(IDS_ERROR_BADARGS);
  808. return(FALSE);
  809. }
  810. lstrcpy( ReturnTextBuffer, Args[0] );
  811. Length = lstrlen( Args[0] );
  812. if( Length == 0 || Args[0][Length - 1] != '\\' ) {
  813. lstrcat( ReturnTextBuffer, "\\" );
  814. }
  815. return( TRUE );
  816. }
  817. BOOL
  818. ProcessForUNC(
  819. IN DWORD cArgs,
  820. IN LPSTR Args[],
  821. OUT LPSTR *TextOut
  822. )
  823. {
  824. SZ szPath;
  825. BOOL IsUNC = FALSE;
  826. DWORD Attr;
  827. *TextOut = ReturnTextBuffer;
  828. if(cArgs != 1) {
  829. SetErrorText(IDS_ERROR_BADARGS);
  830. return(FALSE);
  831. }
  832. szPath = Args[0];
  833. //
  834. // Check to see if UNC
  835. //
  836. if ( lstrlen( szPath ) > 4 &&
  837. szPath[0] == '\\' &&
  838. szPath[1] == '\\' &&
  839. szPath[2] != '\\'
  840. ) {
  841. IsUNC = TRUE;
  842. }
  843. if ( IsUNC ) {
  844. //
  845. // Check to see if UNC path exists. if exists return Path
  846. // else return "UNC-FAILCONNECT"
  847. //
  848. if ((( Attr = GetFileAttributes(szPath) ) != 0xFFFFFFFF) &&
  849. (Attr & FILE_ATTRIBUTE_DIRECTORY )
  850. ) {
  851. lstrcpy ( ReturnTextBuffer, szPath );
  852. }
  853. else {
  854. lstrcpy ( ReturnTextBuffer, "UNC-FAILCONNECT" );
  855. }
  856. }
  857. else {
  858. lstrcpy ( ReturnTextBuffer, "NOT-UNC" );
  859. }
  860. return( TRUE );
  861. }
  862. //
  863. // SetEnvVar <USER | SYSTEM> <ValueName> <ValueTitleIndex> <ValueType> <ValueData>
  864. //
  865. BOOL
  866. SetEnvVar(
  867. IN DWORD cArgs,
  868. IN LPSTR Args[],
  869. OUT LPSTR *TextOut
  870. )
  871. {
  872. *TextOut = ReturnTextBuffer;
  873. if(cArgs != 5) {
  874. SetErrorText(IDS_ERROR_BADARGS);
  875. return(FALSE);
  876. }
  877. return( SetEnvVarWorker( Args[0], Args[1], Args[2], Args[3], Args[4] ) );
  878. }
  879. //
  880. // ExpandSz <String>
  881. //
  882. BOOL
  883. ExpandSz(
  884. IN DWORD cArgs,
  885. IN LPSTR Args[],
  886. OUT LPSTR *TextOut
  887. )
  888. {
  889. *TextOut = ReturnTextBuffer;
  890. if(cArgs != 1) {
  891. SetErrorText(IDS_ERROR_BADARGS);
  892. return(FALSE);
  893. }
  894. return( ExpandSzWorker( Args[0], ReturnTextBuffer, RETURN_BUFFER_SIZE ) );
  895. }
  896. BOOL
  897. ShutdownRemoteSystem(
  898. IN DWORD cArgs,
  899. IN LPSTR Args[],
  900. OUT LPSTR *TextOut
  901. )
  902. {
  903. INT nReturnCode;
  904. *TextOut = ReturnTextBuffer;
  905. if(cArgs != 5) {
  906. SetErrorText(IDS_ERROR_BADARGS);
  907. return(FALSE);
  908. }
  909. nReturnCode = InitiateSystemShutdown(
  910. Args[0], // machinename
  911. Args[1], // shutdown message
  912. (DWORD)atol(Args[2]), // delay
  913. !lstrcmpi(Args[3], "TRUE"), // force apps close
  914. !lstrcmpi(Args[4], "TRUE") // reboot after shutdown
  915. );
  916. return(TRUE);
  917. }
  918. //
  919. // SERVICE CONTROLLER FUNCTIONS:
  920. //
  921. // - TestAdmin
  922. // - SetupCreateService
  923. // - SetupChangeServiceStart
  924. // - SetupChangeServiceConfig
  925. //
  926. //
  927. // TestAdmin: This tries to open the service controller with write access
  928. // and reports whether we have admin privileges in the services
  929. // area.
  930. // (No Args)
  931. BOOL
  932. TestAdmin(
  933. IN DWORD cArgs,
  934. IN LPSTR Args[],
  935. OUT LPSTR *TextOut
  936. )
  937. {
  938. *TextOut = ReturnTextBuffer;
  939. if(cArgs != 0) {
  940. SetErrorText(IDS_ERROR_BADARGS);
  941. return(FALSE);
  942. }
  943. return( TestAdminWorker() );
  944. }
  945. //
  946. // SetupCreateService: To create a service. The parameters passed in are:
  947. //
  948. // arg0: lpServiceName
  949. // arg1: lpDisplayName
  950. // arg2: dwServiceType
  951. // arg3: dwStartType
  952. // arg4: dwErrorControl
  953. // arg5: lpBinaryPathName
  954. // arg6: lpLoadOrderGroup
  955. // arg7: lpDependencies
  956. // arg8: lpServiceStartName
  957. // arg9: lpPassword
  958. //
  959. BOOL
  960. SetupCreateService(
  961. IN DWORD cArgs,
  962. IN LPSTR Args[],
  963. OUT LPSTR *TextOut
  964. )
  965. {
  966. LPSTR lpDependencies = NULL;
  967. BOOL Status;
  968. *TextOut = ReturnTextBuffer;
  969. if(cArgs != 10) {
  970. SetErrorText(IDS_ERROR_BADARGS);
  971. return(FALSE);
  972. }
  973. lpDependencies = ProcessDependencyList( Args[7] );
  974. Status = SetupCreateServiceWorker(
  975. Args[0],
  976. Args[1],
  977. (DWORD)atol( Args[2] ),
  978. (DWORD)atol( Args[3] ),
  979. (DWORD)atol( Args[4] ),
  980. Args[5],
  981. Args[6],
  982. lpDependencies,
  983. Args[8],
  984. Args[9]
  985. );
  986. if( lpDependencies ) {
  987. SFree( lpDependencies );
  988. }
  989. return( Status );
  990. }
  991. //
  992. // SetupChangeServiceStart: To just change the start value of the service
  993. //
  994. // arg0: lpServiceName
  995. // arg1: dwStartType
  996. //
  997. BOOL
  998. SetupChangeServiceStart(
  999. IN DWORD cArgs,
  1000. IN LPSTR Args[],
  1001. OUT LPSTR *TextOut
  1002. )
  1003. {
  1004. *TextOut = ReturnTextBuffer;
  1005. if(cArgs != 2) {
  1006. SetErrorText(IDS_ERROR_BADARGS);
  1007. return(FALSE);
  1008. }
  1009. return( SetupChangeServiceStartWorker(
  1010. Args[0],
  1011. (DWORD)atol( Args[1] )
  1012. ) );
  1013. }
  1014. //
  1015. // SetupChangeServiceConfig: To change the parameters of an existing service.
  1016. // The parameters passed in are:
  1017. //
  1018. // arg0: lpServiceName,
  1019. // arg1: dwServiceType,
  1020. // arg2: dwStartType,
  1021. // arg3: dwErrorControl,
  1022. // arg4: lpBinaryPathName,
  1023. // arg5: lpLoadOrderGroup,
  1024. // arg6: lpDependencies,
  1025. // arg7: lpServiceStartName,
  1026. // arg8: lpPassword,
  1027. // arg9: lpDisplayName
  1028. //
  1029. BOOL
  1030. SetupChangeServiceConfig(
  1031. IN DWORD cArgs,
  1032. IN LPSTR Args[],
  1033. OUT LPSTR *TextOut
  1034. )
  1035. {
  1036. LPSTR lpDependencies = NULL;
  1037. BOOL Status;
  1038. *TextOut = ReturnTextBuffer;
  1039. if(cArgs != 10) {
  1040. SetErrorText(IDS_ERROR_BADARGS);
  1041. return(FALSE);
  1042. }
  1043. lpDependencies = ProcessDependencyList( Args[6] );
  1044. Status = SetupChangeServiceConfigWorker(
  1045. Args[0],
  1046. (DWORD)atol(Args[1]),
  1047. (DWORD)atol(Args[2]),
  1048. (DWORD)atol(Args[3]),
  1049. Args[4],
  1050. Args[5],
  1051. lpDependencies,
  1052. Args[7],
  1053. Args[8],
  1054. Args[9]
  1055. );
  1056. if( lpDependencies ) {
  1057. SFree( lpDependencies );
  1058. }
  1059. return( Status );
  1060. }
  1061. BOOL
  1062. Delnode(
  1063. IN DWORD cArgs,
  1064. IN LPSTR Args[],
  1065. OUT LPSTR *TextOut
  1066. )
  1067. /*++
  1068. Routine Description:
  1069. Perform a recusive deletion starting at a given directory. All files
  1070. and subdirectories are deleted.
  1071. Parameters:
  1072. cArgs - supplies number of arguments. Must be 1, which is the directory
  1073. to delnode.
  1074. Args - supplies an argv-style array of parameters to this routine
  1075. TextOut - receives address of buffer containing error text
  1076. Returns:
  1077. FALSE if argc != 1. TRUE otherwise.
  1078. --*/
  1079. {
  1080. DWORD x;
  1081. PCHAR Directory;
  1082. *TextOut = ReturnTextBuffer;
  1083. *ReturnTextBuffer = '\0';
  1084. if(cArgs != 1) {
  1085. SetErrorText(IDS_ERROR_BADARGS);
  1086. return(FALSE);
  1087. }
  1088. Directory = Args[0];
  1089. //
  1090. // If the given directory ends in \, remove the trailing \.
  1091. //
  1092. if(Directory[x=(lstrlen(Directory)-1)] == TEXT('\\')) {
  1093. Directory[x] = 0;
  1094. }
  1095. DoDelnode(Directory);
  1096. return(TRUE);
  1097. }
  1098. BOOL
  1099. SetCurrentLayout(
  1100. IN DWORD cArgs,
  1101. IN LPSTR Args[],
  1102. OUT LPSTR *TextOut
  1103. )
  1104. {
  1105. *TextOut = ReturnTextBuffer;
  1106. if(cArgs != 1) {
  1107. SetErrorText(IDS_ERROR_BADARGS);
  1108. return(FALSE);
  1109. }
  1110. if( LoadKeyboardLayout(
  1111. Args[0],
  1112. KLF_ACTIVATE
  1113. ) != NULL
  1114. ) {
  1115. SetReturnText( "SUCCESS" );
  1116. }
  1117. else {
  1118. SetReturnText( "FAILED" );
  1119. }
  1120. return( TRUE );
  1121. }
  1122. BOOL
  1123. SetCurrentLocale(
  1124. IN DWORD cArgs,
  1125. IN LPSTR Args[],
  1126. OUT LPSTR *TextOut
  1127. )
  1128. {
  1129. *TextOut = ReturnTextBuffer;
  1130. if(cArgs != 2) {
  1131. SetErrorText(IDS_ERROR_BADARGS);
  1132. return(FALSE);
  1133. }
  1134. if( SetCurrentLocaleWorker( Args[0] , Args[1] ) ) {
  1135. SetReturnText( "SUCCESS" );
  1136. }
  1137. return( TRUE );
  1138. }
  1139. //
  1140. // Error Text routine
  1141. //
  1142. VOID
  1143. SetErrorText(
  1144. IN DWORD ResID
  1145. )
  1146. {
  1147. LoadString(MyDllModuleHandle,(WORD)ResID,ReturnTextBuffer,sizeof(ReturnTextBuffer)-1);
  1148. ReturnTextBuffer[sizeof(ReturnTextBuffer)-1] = '\0'; // just in case
  1149. }
  1150. //
  1151. // Return Text Routine
  1152. //
  1153. VOID
  1154. SetReturnText(
  1155. IN LPSTR Text
  1156. )
  1157. {
  1158. lstrcpy( ReturnTextBuffer, Text );
  1159. }
  1160. //
  1161. // Return a list of indices for a sorted version of the given list.
  1162. // See MISC.C for details.
  1163. //
  1164. BOOL
  1165. GenerateSortedIndexList (
  1166. IN DWORD cArgs,
  1167. IN LPSTR Args[],
  1168. OUT LPSTR *TextOut
  1169. )
  1170. {
  1171. BOOL bAscending, bCaseSens ;
  1172. SZ szIndexList = NULL ;
  1173. *TextOut = ReturnTextBuffer;
  1174. if ( cArgs != 3 )
  1175. {
  1176. SetErrorText(IDS_ERROR_BADARGS);
  1177. return(FALSE);
  1178. }
  1179. bAscending = lstrcmpi( Args[1], "TRUE" ) == 0 ;
  1180. bCaseSens = lstrcmpi( Args[2], "TRUE" ) == 0 ;
  1181. szIndexList = GenerateSortedIntList( Args[0], bAscending, bCaseSens ) ;
  1182. if ( szIndexList == NULL )
  1183. {
  1184. SetErrorText( IDS_ERROR_NO_MEMORY ) ;
  1185. return FALSE ;
  1186. }
  1187. SetReturnText( szIndexList ) ;
  1188. SFree( szIndexList ) ;
  1189. return TRUE ;
  1190. }