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.

843 lines
24 KiB

  1. /*--------------------------------------------------------------------------
  2. setupu.c - setup driver utilitities.
  3. |--------------------------------------------------------------------------*/
  4. #include "precomp.h"
  5. char *szSlash = {"\\"};
  6. char *szSYSTEM = {"SYSTEM"};
  7. char *szCurrentControlSet = {"CurrentControlSet"};
  8. char *szEnum = {"Enum"};
  9. char *szServices = {"Services"};
  10. char *szParameters = {"Parameters"};
  11. char *szSecurity = {"Security"};
  12. char *szLinkage = {"Linkage"};
  13. char *szEventLog = {"EventLog"};
  14. char *szSystem = {"System"};
  15. // just turn debug for this module off
  16. #define D_Level 0
  17. /*----------------------------------------------------------------------
  18. | setup_install_info - Get the version of Windows info, and the source path
  19. of where we are running from
  20. |----------------------------------------------------------------------*/
  21. int APIENTRY setup_install_info(InstallPaths *ip,
  22. HINSTANCE hinst,
  23. char *NewServiceName, // "RocketPort" or "VSLink"
  24. char *NewDriverName, // "rocket.sys" or "vslink.sys"
  25. char *NewAppName, // "Comtrol RocketPort,RocketModem Install"
  26. char *NewAppDir) // "rocket" or "vslink"
  27. {
  28. DWORD ver_info;
  29. char *str;
  30. int i;
  31. struct w_ver_struct {
  32. BYTE win_major;
  33. BYTE win_minor;
  34. BYTE dos_major;
  35. BYTE dos_minor;
  36. } *w_ver;
  37. ver_info = GetVersion();
  38. w_ver = (struct w_ver_struct *) &ver_info;
  39. if (ver_info < 0x80000000)
  40. {
  41. ip->win_type = WIN_NT;
  42. //wsprintf (szVersion, "Microsoft Windows NT %u.%u (Build: %u)",
  43. //(DWORD)(LOBYTE(LOWORD(dwVersion))),
  44. //(DWORD)(HIBYTE(LOWORD(dwVersion))),
  45. // (DWORD)(HIWORD(dwVersion)) );
  46. }
  47. ip->major_ver = w_ver->win_major;
  48. ip->minor_ver = w_ver->win_minor;
  49. if (ip->win_type == WIN_UNKNOWN)
  50. {
  51. ip->win_type = WIN_NT; // force it
  52. }
  53. //GetWindowsDirectory(ip->win_dir,144);
  54. //GetSystemDirectory(ip->system_dir,144);
  55. ip->hinst = hinst;
  56. // Initialize the default source path so that it uses the same
  57. // drive that the SETUP.EXE application was executed from.
  58. GetModuleFileName(hinst, ip->src_dir, sizeof(ip->src_dir));
  59. // chop off file name leaving only the directory
  60. str = ip->src_dir;
  61. i = strlen(str);
  62. if (i > 0) --i;
  63. while ((str[i] != '\\') && (i != 0))
  64. --i;
  65. if (i==0)
  66. str[0] = 0; // problem, no install dir
  67. else
  68. {
  69. str[i] = 0; // terminate over "\"
  70. }
  71. strcpy(ip->szServiceName, NewServiceName);
  72. strcpy(ip->szDriverName, NewDriverName);
  73. strcpy(ip->szAppName, NewAppName);
  74. strcpy(ip->szAppDir, NewAppDir);
  75. GetSystemDirectory(ip->dest_dir, 144);
  76. strcat(ip->dest_dir, "\\");
  77. strcat(ip->dest_dir, NewAppDir);
  78. return 0;
  79. }
  80. /*------------------------------------------------------------------------
  81. | unattended_add_port_entries - Add port entries so that RAS will "see"
  82. some ports which we can install to. Normally the driver puts these
  83. entries in the reg on startup, the reg hardware area gets re-built
  84. every startup. This is a kludge so that unattended install can
  85. go on to add RAS ports.
  86. |------------------------------------------------------------------------*/
  87. int APIENTRY unattended_add_port_entries(InstallPaths *ip,
  88. int num_entries,
  89. int start_port)
  90. {
  91. int i;
  92. static char *szSHDSt = {"HARDWARE\\DEVICEMAP\\SERIALCOMM"};
  93. char szName[120];
  94. char szCom[20];
  95. char str[20];
  96. //DWORD dwstat;
  97. if (start_port == 0)
  98. start_port = 5;
  99. reg_create_key(NULL, szSHDSt); // "HARDWARE\\DEVICEMAP\\SERIALCOMM"
  100. for (i=0; i<num_entries; i++)
  101. {
  102. wsprintf(szCom, "COM%d", i+start_port);
  103. strncpy(szName, ip->szAppDir, strlen(ip->szAppDir) + 1); // "Rocket" or "VSLink"
  104. wsprintf(str, "%d", i);
  105. strncat(szName, str, strlen(str) + 1);
  106. reg_set_str(NULL, szSHDSt, szName, szCom, REG_SZ);
  107. }
  108. return 0;
  109. }
  110. /*-----------------------------------------------------------------
  111. remove_driver_reg_entries -
  112. |------------------------------------------------------------------*/
  113. int APIENTRY remove_driver_reg_entries(char *ServiceName)
  114. {
  115. int stat;
  116. char str[180];
  117. //our_message("Nuking RocketPort Reg Entry",MB_OK);
  118. make_szSCS(str, ServiceName);
  119. stat = reg_delete_key(NULL, str, szEnum);
  120. stat = reg_delete_key(NULL, str, szParameters);
  121. stat = reg_delete_key(NULL, str, szSecurity);
  122. stat = reg_delete_key(NULL, str, szLinkage);
  123. make_szSCS(str, NULL);
  124. stat = reg_delete_key(NULL, str, ServiceName);
  125. if (stat) {
  126. DbgPrintf(D_Level, ("Error 4E\n"))
  127. }
  128. // get rid of the Services\EventLog\..RocketPort entry
  129. make_szSCSES(str, NULL);
  130. stat = reg_delete_key(NULL, str, ServiceName);
  131. if (stat) {
  132. DbgPrintf(D_Level, ("Error 4F\n"))
  133. }
  134. #ifdef NT50
  135. #if 0
  136. remove_pnp_reg_entries();
  137. #endif
  138. #endif
  139. return 0;
  140. }
  141. #if 0
  142. this is experimental
  143. /*--------------------------------------------------------------------------
  144. | remove_pnp_reg_entries -
  145. |--------------------------------------------------------------------------*/
  146. int APIENTRY remove_pnp_reg_entries(void)
  147. {
  148. DWORD stat, keystat;
  149. static char *enum_pci = {"SYSTEM\\CurrentControlSet\\Enum\\PCI"};
  150. static char *enum_root = {"SYSTEM\\CurrentControlSet\\Enum\\root"};
  151. //static char root_name[124];
  152. char node_name[140];
  153. char *pc;
  154. DWORD node_i;
  155. HKEY hKey;
  156. DbgPrintf(D_Level, ("Looking\n"))
  157. keystat = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  158. enum_pci,
  159. 0,
  160. KEY_ENUMERATE_SUB_KEYS | KEY_EXECUTE | KEY_QUERY_VALUE,
  161. &hKey);
  162. if (keystat != ERROR_SUCCESS)
  163. {
  164. DbgPrintf(D_Level, ("Err14a\n"))
  165. return 1;
  166. }
  167. node_i = 0;
  168. stat = RegEnumKey (hKey, node_i++, node_name, 138);
  169. while (stat == ERROR_SUCCESS)
  170. {
  171. pc = node_name;
  172. while (*pc)
  173. {
  174. *pc = toupper(*pc);
  175. ++pc;
  176. }
  177. if (strstr(node_name, "VEN_11FE") != 0)
  178. {
  179. // found a Comtrol hardware node
  180. DbgPrintf(D_Level, ("Found Node:%s\n", node_name))
  181. stat = RegDeleteKeyNT(hKey, node_name);
  182. if (stat != ERROR_SUCCESS)
  183. {
  184. DbgPrintf(D_Level, ("No Delete\n"))
  185. }
  186. //stat = reg_delete_key(NULL, node_name, node_name);
  187. }
  188. stat = RegEnumKey (hKey, node_i++, node_name, 68);
  189. }
  190. RegCloseKey (hKey); // Close the key handle.
  191. return 0;
  192. }
  193. #endif
  194. /*--------------------------------------------------------------------------
  195. RegDeleteKeyNT -
  196. A registry key that is opened by an application can be deleted
  197. without error by another application in both Windows 95 and
  198. Windows NT. This is by design.
  199. |--------------------------------------------------------------------------*/
  200. DWORD APIENTRY RegDeleteKeyNT(HKEY hStartKey , LPTSTR pKeyName )
  201. {
  202. DWORD dwRtn, dwSubKeyLength;
  203. LPTSTR pSubKey = NULL;
  204. TCHAR szSubKey[256]; // (256) this should be dynamic.
  205. HKEY hKey;
  206. // do not allow NULL or empty key name
  207. if ( pKeyName && lstrlen(pKeyName))
  208. {
  209. if( (dwRtn=RegOpenKeyEx(hStartKey,pKeyName,
  210. 0, KEY_ENUMERATE_SUB_KEYS | DELETE, &hKey )) == ERROR_SUCCESS)
  211. {
  212. while (dwRtn == ERROR_SUCCESS )
  213. {
  214. dwSubKeyLength = 250;
  215. dwRtn=RegEnumKeyEx(
  216. hKey,
  217. 0, // always index zero
  218. szSubKey,
  219. &dwSubKeyLength,
  220. NULL,
  221. NULL,
  222. NULL,
  223. NULL
  224. );
  225. if(dwRtn == ERROR_NO_MORE_ITEMS)
  226. {
  227. dwRtn = RegDeleteKey(hStartKey, pKeyName);
  228. break;
  229. }
  230. else if(dwRtn == ERROR_SUCCESS)
  231. dwRtn=RegDeleteKeyNT(hKey, szSubKey);
  232. }
  233. RegCloseKey(hKey);
  234. // Do not save return code because error
  235. // has already occurred
  236. }
  237. else
  238. {
  239. DbgPrintf(D_Level, ("Access Error\n"))
  240. }
  241. }
  242. else
  243. dwRtn = ERROR_BADKEY;
  244. return dwRtn;
  245. }
  246. /*---------------------------------------------------------------------------
  247. | modem_inf_change - go make the needed changes to the modem.inf file.
  248. | Make a backup copy too.
  249. |----------------------------------------------------------------------------*/
  250. int APIENTRY modem_inf_change(InstallPaths *ip,
  251. char *modemfile,
  252. char *szModemInfEntry)
  253. {
  254. int i=0;
  255. int stat = 1;
  256. OUR_FILE *fp; // in
  257. OUR_FILE *fp2; // out
  258. OUR_FILE *fp_new; // entries file to add
  259. char buf[202];
  260. char *str;
  261. char *szRAS={"\\RAS\\"};
  262. int section = 0;
  263. int chk;
  264. DbgPrintf(D_Level, ("chg inf start\n"))
  265. // first backup original modem.inf if not done already.
  266. stat = backup_modem_inf(ip);
  267. if (stat)
  268. return 1; // err, couldn't backup modem.inf
  269. DbgPrintf(D_Level, ("chg A\n"))
  270. GetSystemDirectory(buf, 144);
  271. strcat(buf,"\\");
  272. strcat(buf,modemfile);
  273. fp_new = our_fopen(buf, "rb"); // rocket\rocket35.inf
  274. DbgPrintf(D_Level, ("chg B\n"))
  275. if (fp_new == NULL)
  276. {
  277. wsprintf(ip->tmpstr,RcStr((MSGSTR+15)),buf);
  278. stat = our_message(ip, ip->tmpstr, MB_OK);
  279. return 1;
  280. }
  281. GetSystemDirectory(ip->dest_str, 144);
  282. strcat(ip->dest_str, szRAS);
  283. strcat(ip->dest_str,"modem.inf");
  284. //----- now copy modem.inf to modem.rk0 as a base to read from and
  285. // write new file
  286. GetSystemDirectory(ip->src_str, 144);
  287. strcat(ip->src_str, szRAS);
  288. strcat(ip->src_str,"modem.rk0");
  289. stat = our_copy_file(ip->src_str, ip->dest_str);
  290. if (stat)
  291. {
  292. wsprintf(ip->tmpstr,RcStr((MSGSTR+16)), ip->dest_str, ip->src_str, stat);
  293. stat = our_message(ip, ip->tmpstr, MB_OK);
  294. return 2; // err
  295. }
  296. fp = our_fopen(ip->src_str, "rb"); // modem.rk0
  297. if (fp == NULL)
  298. {
  299. wsprintf(ip->tmpstr,RcStr((MSGSTR+17)), ip->src_str);
  300. stat = our_message(ip, ip->tmpstr, MB_OK);
  301. return 1;
  302. }
  303. fp2 = our_fopen(ip->dest_str, "wb"); // modem.inf
  304. if (fp2 == NULL)
  305. {
  306. wsprintf(ip->tmpstr, "Tried to open the %s file for changes, but could not open it.", ip->dest_str);
  307. our_fclose(fp);
  308. return 1;
  309. }
  310. chk = 0;
  311. while ((our_fgets(buf, 200, fp)) && (!our_feof(fp)) && (!our_ferror(fp)) && (!our_ferror(fp2)) &&
  312. (chk < 30000))
  313. {
  314. ++chk;
  315. // search and kill any 0x1a eof markers
  316. str = buf;
  317. while (*str != 0)
  318. {
  319. if (*str == 0x1a)
  320. *str = ' '; // change eof to space
  321. ++str;
  322. }
  323. // pass up spaces
  324. str = buf;
  325. while (*str == ' ')
  326. ++str;
  327. if (*str == '[')
  328. {
  329. if (str[0] == '[') // starting new section
  330. {
  331. section = 0; // not our section to worry about
  332. if (my_substr_lstricmp(str, szModemInfEntry) == 0) // match
  333. {
  334. // make sure
  335. section = 1;
  336. }
  337. } // end of new [] section header
  338. }
  339. // process all entries here
  340. if (section == 1)
  341. str[0] = 0; // first delete all "[Comtrol RocketModem]" entries
  342. if (str[0] != 0)
  343. {
  344. str = buf; // don't skip spaces
  345. our_fputs(buf,fp2);
  346. }
  347. } // end of while fgets();
  348. stat = 0;
  349. if ( (our_ferror(fp)) || (our_ferror(fp2)) || (chk >= 10000))
  350. {
  351. stat = 3; // error
  352. }
  353. if (stat)
  354. {
  355. our_fclose(fp);
  356. our_fclose(fp2);
  357. our_fclose(fp_new);
  358. // try to restore to the read file backup(modem.rk0)
  359. stat = our_copy_file(ip->dest_str, ip->src_str);
  360. wsprintf(ip->tmpstr, "Errors encountered while making %s file changes.", ip->dest_str);
  361. stat = 3; // error
  362. }
  363. else
  364. {
  365. // append the changes to it
  366. our_fputs("\x0d\x0a",fp2);
  367. our_fputs(szModemInfEntry, fp2);
  368. our_fputs("\x0d\x0a;-------------------\x0d\x0a",fp2);
  369. while ((our_fgets(buf, 200, fp_new)) && (!our_feof(fp_new)) && (!our_ferror(fp2)))
  370. {
  371. our_fputs(buf,fp2);
  372. }
  373. our_fclose(fp);
  374. our_fclose(fp2);
  375. our_fclose(fp_new);
  376. our_remove(ip->src_str); // kill temporary modem.rk0 file
  377. }
  378. return stat;
  379. }
  380. /*---------------------------------------------------------------------------
  381. | backup_modem_inf - backs up to modem.bak.
  382. |----------------------------------------------------------------------------*/
  383. int APIENTRY backup_modem_inf(InstallPaths *ip)
  384. {
  385. int stat = 1;
  386. char *szRAS = {"\\RAS\\"};
  387. OUR_FILE *fp;
  388. // first copy modem.inf over to our directory as a backup
  389. GetSystemDirectory(ip->dest_str, 144);
  390. strcat(ip->dest_str, szRAS);
  391. strcat(ip->dest_str,"modem.bak");
  392. GetSystemDirectory(ip->src_str, 144);
  393. strcat(ip->src_str, szRAS);
  394. strcat(ip->src_str,"modem.inf");
  395. fp = our_fopen(ip->dest_str, "rb"); // see if already backed up
  396. if (fp == NULL)
  397. {
  398. stat = our_copy_file(ip->dest_str, ip->src_str);
  399. if (stat != 0)
  400. {
  401. wsprintf(ip->tmpstr,RcStr((MSGSTR+18)), ip->src_str, stat);
  402. our_message(ip, ip->tmpstr, MB_OK);
  403. return 1; // err
  404. }
  405. }
  406. else our_fclose(fp);
  407. return 0; // ok
  408. }
  409. /*---------------------------------------------------------------------------
  410. | service_man - Handle installation, removal, starting, stopping of NT
  411. services(or drivers.).
  412. |----------------------------------------------------------------------------*/
  413. int APIENTRY service_man(LPSTR lpServiceName, LPSTR lpBinaryPath, int chore)
  414. {
  415. SC_HANDLE hSCManager = NULL;
  416. SC_HANDLE hService = NULL;
  417. SC_LOCK lSCLock = NULL;
  418. // SERVICE_STATUS ServiceStatus;
  419. BOOL Status = 1; // success
  420. int stat = 0; // ret status(0=ok)
  421. hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
  422. if (hSCManager == NULL)
  423. {
  424. return 2;
  425. }
  426. //---- Lock the service database
  427. lSCLock = LockServiceDatabase( hSCManager );
  428. if (lSCLock == NULL)
  429. {
  430. CloseServiceHandle( hSCManager );
  431. return 1;
  432. }
  433. if ((chore != CHORE_INSTALL) && (chore != CHORE_INSTALL_SERVICE))
  434. {
  435. hService = OpenService( hSCManager, lpServiceName, SERVICE_ALL_ACCESS);
  436. if (hService == NULL)
  437. {
  438. UnlockServiceDatabase( lSCLock );
  439. CloseServiceHandle( hSCManager );
  440. return 2;
  441. }
  442. }
  443. switch(chore)
  444. {
  445. case CHORE_INSTALL:
  446. // Create the service
  447. hService = CreateService( hSCManager,
  448. lpServiceName, // Service's name
  449. lpServiceName, // Display name (new for NT)
  450. SERVICE_ALL_ACCESS,// Access (allow all)
  451. SERVICE_KERNEL_DRIVER, // Service type
  452. SERVICE_AUTO_START, // Startup behavior
  453. 0x1, // Error control
  454. lpBinaryPath, // Full pathname of binary
  455. NULL, // Load order group
  456. NULL, // Tag ID
  457. NULL, // Dependencies (none)
  458. NULL, // Account name
  459. NULL // Password
  460. );
  461. if (hService == NULL)
  462. stat = 5;
  463. Status = 0;
  464. break;
  465. case CHORE_START:
  466. // Unlock the database
  467. if (lSCLock != NULL)
  468. {
  469. UnlockServiceDatabase( lSCLock );
  470. lSCLock = NULL;
  471. }
  472. Status = StartService(hService, 0, NULL);
  473. //if (Status !=
  474. if (Status == 0) // false
  475. {
  476. stat = GetLastError();
  477. Status = 1;
  478. }
  479. break;
  480. case CHORE_STOP:
  481. {
  482. SERVICE_STATUS ss;
  483. Status = ControlService(hService, SERVICE_CONTROL_STOP, &ss);
  484. if (Status == 0) // false
  485. {
  486. stat = GetLastError();
  487. if (stat == 0)
  488. stat = 1234;
  489. Status = 1;
  490. }
  491. }
  492. break;
  493. case CHORE_REMOVE:
  494. Status = DeleteService(hService);
  495. break;
  496. case CHORE_INSTALL_SERVICE:
  497. // Create the service
  498. hService = CreateService( hSCManager,
  499. lpServiceName, // Service's name
  500. lpServiceName, // Display name (new for NT)
  501. SERVICE_ALL_ACCESS,// Access (allow all)
  502. SERVICE_WIN32_OWN_PROCESS, // Service type
  503. SERVICE_AUTO_START, // Startup behavior
  504. SERVICE_ERROR_NORMAL, // Error control
  505. lpBinaryPath, // Full pathname of binary
  506. NULL, // Load order group
  507. NULL, // Tag ID
  508. NULL, // Dependencies (none)
  509. NULL, // Account name
  510. NULL // Password
  511. );
  512. if (hService == NULL)
  513. stat = 6;
  514. //Status = 0;
  515. break;
  516. case CHORE_IS_INSTALLED:
  517. // return without error to indicate it is installed.
  518. break;
  519. }
  520. if (Status == 0) // false
  521. stat = 8;
  522. // Close our handle to the new service
  523. if (hService != NULL)
  524. CloseServiceHandle(hService);
  525. // Unlock the database
  526. if (lSCLock != NULL)
  527. UnlockServiceDatabase( lSCLock );
  528. // Free our handle to the service control manager
  529. CloseServiceHandle( hSCManager );
  530. return stat;
  531. }
  532. /*-----------------------------------------------------------------
  533. make_szSCS - Services area.
  534. form ascii string: "SYSTEM\CurrentControlSet\Services"
  535. |------------------------------------------------------------------*/
  536. int APIENTRY make_szSCS(char *str, const char *szName)
  537. {
  538. strcpy(str, szSYSTEM); strcat(str, szSlash);
  539. strcat(str, szCurrentControlSet); strcat(str, szSlash);
  540. strcat(str, szServices);
  541. if (szName != NULL)
  542. {
  543. strcat(str, szSlash);
  544. strcat(str, szName);
  545. }
  546. return 0;
  547. }
  548. /*-----------------------------------------------------------------
  549. make_szSCSES - Event log reg area
  550. form ascii string: "SYSTEM\CurrentControlSet\Services\EventLog\System"
  551. |------------------------------------------------------------------*/
  552. int APIENTRY make_szSCSES(char *str, const char *szName)
  553. {
  554. strcpy(str, szSYSTEM); strcat(str, szSlash);
  555. strcat(str, szCurrentControlSet); strcat(str, szSlash);
  556. strcat(str, szServices); strcat(str, szSlash);
  557. strcat(str, szEventLog); strcat(str, szSlash);
  558. strcat(str, szSystem);
  559. if (szName != NULL)
  560. {
  561. strcat(str, szSlash);
  562. strcat(str, szName);
  563. }
  564. return 0;
  565. }
  566. /*---------------------------------------------------------------------------
  567. | copy_files - copy a list of files from wi->src_dir to wi->dest_dir
  568. | Uses the wi->src_str & wi->dest_str. Assumes you want the same name
  569. | as copying from.
  570. |----------------------------------------------------------------------------*/
  571. int APIENTRY copy_files(InstallPaths *ip, char **files)
  572. {
  573. int i=0;
  574. int stat;
  575. if (my_lstricmp(ip->src_dir, ip->dest_dir) == 0) // src_dir == dest_drv
  576. return 0;
  577. while (files[i] != NULL)
  578. {
  579. strcpy(ip->src_str, ip->src_dir);
  580. strcat(ip->src_str, szSlash);
  581. strcat(ip->src_str, files[i]);
  582. strcpy(ip->dest_str, ip->dest_dir);
  583. strcat(ip->dest_str, szSlash);
  584. strcat(ip->dest_str, files[i]);
  585. again1:
  586. stat = our_copy_file(ip->dest_str, ip->src_str);
  587. if (stat)
  588. {
  589. //if (stat == 1) // error opening read file
  590. // return 1; // don't report errors, since some driver sets differ in
  591. // which files they include
  592. // (that was a stupid idea(karl to karl)!)
  593. wsprintf(ip->tmpstr,RcStr((MSGSTR+19)), ip->src_str, ip->dest_str);
  594. stat = our_message(ip, ip->tmpstr, MB_ABORTRETRYIGNORE);
  595. if (stat == IDABORT)
  596. return 1; // error
  597. if (stat == IDRETRY) goto again1;
  598. }
  599. ++i;
  600. }
  601. return 0;
  602. }
  603. /*---------------------------------------------------------------------------
  604. | our_copy_file - copy a file from here to there.
  605. |----------------------------------------------------------------------------*/
  606. int APIENTRY our_copy_file(char *dest, char *src)
  607. {
  608. int stat;
  609. // just use the stock Win32 function
  610. stat = CopyFile(src, dest,
  611. 0); // 1=fail if exist
  612. if (stat)
  613. return 0; // ok, worked
  614. return 1; // failed
  615. #ifdef COMMENT_OUT
  616. char *buf;
  617. unsigned int bytes, wbytes;
  618. int err = 0;
  619. int chk = 0;
  620. OUR_FILE *fp1, *fp2;
  621. buf = (char *) malloc(0x4010);
  622. if (buf == NULL)
  623. {
  624. //our_message("Error, no memory",MB_OK);
  625. return 6; // no mem
  626. }
  627. fp1 = our_fopen(src,"rb");
  628. if (fp1 == NULL)
  629. {
  630. //our_message("Error Opening to read",MB_OK);
  631. free(buf);
  632. return 1; // no src
  633. }
  634. fp2 = our_fopen(dest,"wb");
  635. if (fp2 == NULL)
  636. {
  637. //our_message("Error Opening to write",MB_OK);
  638. free(buf);
  639. our_fclose(fp1);
  640. return 2; /* err opening dest */
  641. }
  642. bytes = our_fread(buf, 1, 0x4000, fp1);
  643. while ((bytes > 0) && (!err))
  644. {
  645. ++chk;
  646. if (chk > 10000)
  647. err = 5;
  648. wbytes = our_fwrite(buf, 1, bytes, fp2);
  649. if (wbytes != bytes)
  650. {
  651. err = 3;
  652. }
  653. bytes = our_fread(buf, 1, 0x4000, fp1);
  654. if (our_ferror(fp1))
  655. {
  656. //our_message("Error reading",MB_OK);
  657. err = 4;
  658. }
  659. if (our_ferror(fp2))
  660. {
  661. //our_message("Error writing",MB_OK);
  662. err = 6;
  663. }
  664. }
  665. free(buf);
  666. our_fclose(fp1);
  667. our_fclose(fp2);
  668. return err; // 0=ok, else error
  669. #endif
  670. }
  671. /*-----------------------------------------------------------------------------
  672. | our_message -
  673. |-----------------------------------------------------------------------------*/
  674. int APIENTRY our_message(InstallPaths *ip, char *str, WORD option)
  675. {
  676. if (ip->prompting_off)
  677. {
  678. // we are doing unattended install, and don't want user interface
  679. // popping up. So just say YES or OK to all prompts.
  680. if (option == MB_YESNO)
  681. return IDYES;
  682. return IDOK;
  683. }
  684. return MessageBox(GetFocus(), str, ip->szAppName, option);
  685. }
  686. /*-----------------------------------------------------------------------------
  687. | load_str -
  688. |-----------------------------------------------------------------------------*/
  689. int APIENTRY load_str(HINSTANCE hinst, int id, char *dest, int str_size)
  690. {
  691. dest[0] = 0;
  692. if (!LoadString(hinst, id, dest, str_size) )
  693. {
  694. wsprintf(dest,"Err,str-id %d", id);
  695. MessageBox(GetFocus(), dest, "Error", MB_OK);
  696. return 1;
  697. }
  698. return 0;
  699. }
  700. #if 0
  701. /*-----------------------------------------------------------------------------
  702. | our_id_message -
  703. |-----------------------------------------------------------------------------*/
  704. int APIENTRY our_id_message(InstallPaths *ip, int id, WORD prompt)
  705. {
  706. int stat;
  707. if (ip->prompting_off)
  708. {
  709. // we are doing unattended install, and don't want user interface
  710. // popping up. So just say YES or OK to all prompts.
  711. if (option == MB_YESNO)
  712. return IDYES;
  713. return IDOK;
  714. }
  715. load_str(ip->hinst, id, ip->tmpstr, CharSizeOf(ip->tmpstr));
  716. stat = our_message(ip, ip->tmpstr, prompt);
  717. return stat;
  718. }
  719. #endif
  720. /*---------------------------------------------------------------------------
  721. | mess - message
  722. |---------------------------------------------------------------------------*/
  723. void APIENTRY mess(InstallPaths *ip, char *format, ...)
  724. {
  725. va_list next;
  726. char buf[200];
  727. if (ip->prompting_off)
  728. return;
  729. va_start(next, format);
  730. vsprintf(buf, format, next);
  731. MessageBox(GetFocus(), buf, ip->szAppName, MB_OK);
  732. }
  733. TCHAR *
  734. RcStr( int MsgIndex )
  735. {
  736. static TCHAR RcStrBuf[200];
  737. load_str(glob_hinst, MsgIndex, RcStrBuf, CharSizeOf(RcStrBuf) );
  738. if (!LoadString(glob_hinst, MsgIndex, RcStrBuf, CharSizeOf(RcStrBuf)) ) {
  739. wsprintf(RcStrBuf,"Err, str-id %d", MsgIndex);
  740. }
  741. return RcStrBuf;
  742. }