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.

1362 lines
33 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* WFUTIL.C - */
  4. /* */
  5. /* Windows File System String Utility Functions */
  6. /* */
  7. /****************************************************************************/
  8. #include "winfile.h"
  9. #include "lfn.h"
  10. #include "winnet.h"
  11. #include "wnetcaps.h" // WNetGetCaps()
  12. #include "stdlib.h"
  13. int rgiDriveType[26];
  14. PSTR CurDirCache[26];
  15. // cache GetDriveType calls for speed
  16. INT
  17. DriveType(
  18. INT iDrive
  19. )
  20. {
  21. if (rgiDriveType[iDrive] != -1)
  22. return rgiDriveType[iDrive];
  23. return rgiDriveType[iDrive] = MGetDriveType(iDrive);
  24. }
  25. VOID
  26. InvalidateDriveType()
  27. {
  28. INT i;
  29. for (i = 0; i < 26; i++)
  30. rgiDriveType[i] = -1;
  31. }
  32. // iDrive zero based drive number (0 = A, 1 = B)
  33. // returns:
  34. // TRUE we have it saved pszPath gets path
  35. // FALSE we don't have it saved
  36. BOOL
  37. APIENTRY
  38. GetSavedDirectory(
  39. INT iDrive,
  40. PSTR pszPath
  41. )
  42. {
  43. if (CurDirCache[iDrive]) {
  44. lstrcpy(pszPath, CurDirCache[iDrive]);
  45. return TRUE;
  46. } else
  47. return FALSE;
  48. }
  49. VOID
  50. APIENTRY
  51. SaveDirectory(
  52. PSTR pszPath
  53. )
  54. {
  55. INT i;
  56. i = DRIVEID(pszPath);
  57. if (CurDirCache[i])
  58. LocalFree((HANDLE)CurDirCache[i]);
  59. CurDirCache[i] = (PSTR)LocalAlloc(LPTR, lstrlen(pszPath)+1);
  60. if (CurDirCache[i])
  61. lstrcpy(CurDirCache[i], pszPath);
  62. }
  63. /*
  64. * GetSelectedDrive() -
  65. *
  66. * Get the selected drive from the currently active window
  67. *
  68. * should be in wfutil.c
  69. */
  70. INT
  71. APIENTRY
  72. GetSelectedDrive()
  73. {
  74. HWND hwnd;
  75. hwnd = (HWND)SendMessage(hwndMDIClient,WM_MDIGETACTIVE,0,0L);
  76. return (INT)SendMessage(hwnd,FS_GETDRIVE,0,0L) - (INT)'A';
  77. }
  78. /*
  79. * GetSelectedDirectory() -
  80. *
  81. * Gets the directory selected for the drive. uses the windows
  82. * z-order to give precidence to windows higher in the order.
  83. *
  84. * works like GetCurrentDirectory() except it looks through
  85. * the window list for directories first (and returns ANSI)
  86. *
  87. * returns:
  88. * lpDir ANSI string of current dir
  89. */
  90. VOID
  91. APIENTRY
  92. GetSelectedDirectory(
  93. WORD iDrive,
  94. PSTR pszDir
  95. )
  96. {
  97. HWND hwnd;
  98. WORD iDriveT;
  99. if (iDrive) {
  100. for (hwnd = GetWindow(hwndMDIClient,GW_CHILD);
  101. hwnd;
  102. hwnd = GetWindow(hwnd,GW_HWNDNEXT)) {
  103. iDriveT = (WORD)SendMessage(hwnd,FS_GETDRIVE,0,0L);
  104. if (iDrive == (WORD)(iDriveT - 'A' + 1))
  105. goto hwndfound;
  106. }
  107. if (!GetSavedDirectory(iDrive - 1, pszDir)) {
  108. SheGetDir(iDrive,pszDir);
  109. OemToAnsi(pszDir,pszDir);
  110. }
  111. return;
  112. } else
  113. hwnd = (HWND)SendMessage(hwndMDIClient,WM_MDIGETACTIVE,0,0L);
  114. hwndfound:
  115. SendMessage(hwnd,FS_GETDIRECTORY,MAXPATHLEN,(LPARAM)pszDir);
  116. StripBackslash(pszDir);
  117. }
  118. // avoid confusion in DOSs upper case mapping by converting to
  119. // upper case before passing down to dos
  120. VOID
  121. APIENTRY
  122. FixAnsiPathForDos(
  123. LPSTR szPath
  124. )
  125. {
  126. if (GetNameType(szPath) == FILE_83_CI)
  127. AnsiUpper(szPath);
  128. AnsiToOem(szPath, szPath);
  129. }
  130. // refresh a MDI child window (works for any type of mdi child)
  131. VOID
  132. APIENTRY
  133. RefreshWindow(
  134. HWND hwndActive
  135. )
  136. {
  137. HWND hwndTree, hwndDir;
  138. LPARAM lParam;
  139. CHAR szDir[MAXPATHLEN];
  140. INT iDrive;
  141. cDrives = UpdateDriveList(); // updates rgiDrive[]
  142. InitDriveBitmaps();
  143. // make sure the thing is still there (floppy drive, net drive)
  144. iDrive = (INT)GetWindowLong(hwndActive, GWL_TYPE);
  145. if ((iDrive >= 0) && !CheckDrive(hwndActive, iDrive))
  146. return;
  147. // update the dir part first so tree can steal later
  148. if (hwndDir = HasDirWindow(hwndActive))
  149. SendMessage(hwndDir, FS_CHANGEDISPLAY, CD_PATH, 0L);
  150. if (hwndTree = HasTreeWindow(hwndActive)) {
  151. // remember the current directory
  152. SendMessage(hwndActive, FS_GETDIRECTORY, sizeof(szDir), (LPARAM)szDir);
  153. // update the drives windows
  154. SendMessage(hwndActive, FS_CHANGEDRIVES, 0, 0L);
  155. if (IsValidDisk(szDir[0] - 'A'))
  156. lParam = (LPARAM)szDir;
  157. else
  158. lParam = 0;
  159. // update the tree
  160. SendMessage(hwndTree, TC_SETDRIVE, MAKEWORD(FALSE, TRUE), lParam);
  161. }
  162. if (hwndActive == hwndSearch)
  163. SendMessage(hwndActive, FS_CHANGEDISPLAY, CD_PATH, 0L);
  164. }
  165. VOID
  166. APIENTRY
  167. CheckEscapes(
  168. LPSTR szFile
  169. )
  170. {
  171. CHAR szT[MAXPATHLEN];
  172. CHAR *p, *pT;
  173. for (p = szFile; *p; p = (LPSTR)AnsiNext(p)) {
  174. switch (*p) {
  175. case ' ':
  176. case ',':
  177. case ';':
  178. case '^':
  179. case '"':
  180. {
  181. // this path contains an annoying character
  182. lstrcpy(szT,szFile);
  183. p = szFile;
  184. *p++ = '"';
  185. for (pT = szT; *pT; ) {
  186. if (*pT == '^' || *pT == '"')
  187. *p++ = '^';
  188. if (IsDBCSLeadByte(*p++ = *pT++))
  189. *p++ = *pT++;
  190. }
  191. *p++ = '"';
  192. *p = 0;
  193. return;
  194. }
  195. }
  196. }
  197. }
  198. HWND
  199. APIENTRY
  200. GetRealParent(
  201. HWND hwnd
  202. )
  203. {
  204. // run up the parent chain until you find a hwnd
  205. // that doesn't have WS_CHILD set
  206. while (GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD)
  207. hwnd = (HWND)GetWindowLongPtr(hwnd, GWLP_HWNDPARENT);
  208. return hwnd;
  209. }
  210. VOID
  211. APIENTRY
  212. WFHelp(
  213. HWND hwnd
  214. )
  215. {
  216. if (!WinHelp(hwnd, szWinObjHelp, HELP_CONTEXT, dwContext)) {
  217. MyMessageBox(hwnd, IDS_WINFILE, IDS_WINHELPERR, MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
  218. }
  219. }
  220. BOOL
  221. APIENTRY
  222. IsLastWindow()
  223. {
  224. HWND hwnd;
  225. INT count;
  226. count = 0;
  227. // count all non title/search windows to see if close is allowed
  228. for (hwnd = GetWindow(hwndMDIClient, GW_CHILD); hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT))
  229. if (!GetWindow(hwnd, GW_OWNER) && ((INT)GetWindowLong(hwnd, GWL_TYPE) >= 0))
  230. count++;
  231. return count == 1;
  232. }
  233. // get connection information including disconnected drives
  234. //
  235. // in:
  236. // lpDev device name "A:" "LPT1:", etc.
  237. // fClosed if FALSE closed or error drives will be converted to
  238. // WN_SUCCESS return codes. if TRUE return not connected
  239. // and error state values (ie, the caller knows about not
  240. // connected and error state drives)
  241. // out:
  242. // lpPath filled with net name if return is WN_SUCCESS (or not connected/error)
  243. // returns:
  244. // WN_* error code
  245. WORD
  246. APIENTRY
  247. WFGetConnection(
  248. LPSTR lpDev,
  249. LPSTR lpPath,
  250. BOOL fClosed
  251. )
  252. {
  253. DWORD cb;
  254. UINT err;
  255. UINT caps;
  256. cb = 64;
  257. caps = WNetGetCaps(WNNC_CONNECTION);
  258. if (caps & WNNC_CON_GETCONNECTIONS)
  259. err = WNetGetConnection(lpDev,lpPath,&cb);
  260. else
  261. return WN_NOT_CONNECTED;
  262. if (err == WN_NOT_CONNECTED &&
  263. !(caps & WNNC_CON_RESTORECONNECTION)) {
  264. if (GetProfileString(szNetwork,lpDev,szNULL,lpPath,64))
  265. err = WN_CONNECTION_CLOSED;
  266. }
  267. if (!fClosed)
  268. if (err == WN_CONNECTION_CLOSED || err == WN_DEVICE_ERROR)
  269. err = WN_SUCCESS;
  270. return (WORD)err;
  271. }
  272. // returns the number of this MDI window as well as returning
  273. // the text with the number stripped off
  274. //
  275. // returns:
  276. // 0 this title doesn't have a number
  277. // > 0 the title number
  278. // szTitle the title with the number stripped off
  279. INT
  280. APIENTRY
  281. GetMDIWindowText(
  282. HWND hWnd,
  283. LPSTR szTitle,
  284. INT size
  285. )
  286. {
  287. LPSTR lp, lpLast;
  288. ENTER("GetMDIWindowText");
  289. GetWindowText(hWnd, szTitle, size);
  290. lpLast = NULL;
  291. for (lp = szTitle; *lp; lp = AnsiNext(lp))
  292. if (*lp == ':')
  293. lpLast = lp;
  294. if (lpLast) {
  295. *lpLast++ = 0;
  296. PRINT(BF_PARMTRACE, "OUT: szTitle=%s", szTitle);
  297. PRINT(BF_PARMTRACE, "OUT: window#=%s", lpLast);
  298. LEAVE("GetMDIWindowText");
  299. return atoi(lpLast); // return the window number
  300. } else {
  301. TRACE(BF_PARMTRACE, "OUT: window#=0");
  302. LEAVE("GetMDIWindowText");
  303. return 0; // no number on this
  304. }
  305. }
  306. // set the MDI window text and add a ":#" on the end if
  307. // there is another window with the same title. this is to
  308. // avoid confusion when there are multiple MDI children
  309. // with the same title. be sure to use GetMDIWindowText to
  310. // strip off the number stuff.
  311. VOID
  312. APIENTRY
  313. SetMDIWindowText(
  314. HWND hWnd,
  315. LPSTR szTitle
  316. )
  317. {
  318. CHAR szTemp[MAXPATHLEN];
  319. CHAR szNumber[20];
  320. HWND hwnd;
  321. INT num, max_num;
  322. ENTER("SetMDIWindowText");
  323. PRINT(BF_PARMTRACE, "hWnd=%lx", hWnd);
  324. PRINT(BF_PARMTRACE, "IN: szTitle=%s", szTitle);
  325. max_num = 0;
  326. for (hwnd = GetWindow(hwndMDIClient, GW_CHILD); hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT)) {
  327. num = GetMDIWindowText(hwnd, szTemp, sizeof(szTemp));
  328. if (!lstrcmp(szTemp, szTitle)) {
  329. if (hwnd == hWnd)
  330. continue;
  331. if (!num) {
  332. lstrcat(szTemp, ":1");
  333. // if (wTextAttribs & TA_LOWERCASE)
  334. // AnsiLower(szTemp);
  335. SetWindowText(hwnd, szTemp);
  336. num = 1;
  337. }
  338. max_num = max(max_num, num);
  339. }
  340. }
  341. if (max_num) {
  342. wsprintf(szNumber, ":%d", max_num+1);
  343. lstrcat(szTitle, szNumber);
  344. }
  345. // if (wTextAttribs & TA_LOWERCASE)
  346. // AnsiLower(szTitle);
  347. SetWindowText(hWnd, szTitle);
  348. PRINT(BF_PARMTRACE, "OUT: szTitle=%s", szTitle);
  349. LEAVE("SetMDIWindowText");
  350. }
  351. #define ISDIGIT(c) ((c) >= '0' && (c) <= '9')
  352. #ifdef INLIBRARY
  353. INT
  354. APIENTRY
  355. atoi(
  356. LPSTR sz
  357. )
  358. {
  359. INT n = 0;
  360. BOOL bNeg = FALSE;
  361. if (*sz == '-') {
  362. bNeg = TRUE;
  363. sz++;
  364. }
  365. while (ISDIGIT(*sz)) {
  366. n *= 10;
  367. n += *sz - '0';
  368. sz++;
  369. }
  370. return bNeg ? -n : n;
  371. }
  372. #endif
  373. // fills in rgiDrive[] and returns the number of drives
  374. INT
  375. APIENTRY
  376. UpdateDriveList()
  377. {
  378. INT i, cRealDrives = 0;
  379. DWORD dwDrives;
  380. dwDrives = GetLogicalDrives();
  381. for (i = 0; i < 26; i++) {
  382. if ((1 << i) & dwDrives) {
  383. rgiDrive[cRealDrives++] = i;
  384. rgiDriveType[i] = MGetDriveType(i);
  385. } else {
  386. rgiDrive[i] = 0;
  387. rgiDriveType[i] = -1; // invalidate the drivetype
  388. }
  389. if (apVolInfo[i]) { // sothat volinfo is refreshed
  390. LocalFree(apVolInfo[i]);
  391. apVolInfo[i] = NULL;
  392. }
  393. }
  394. return cRealDrives;
  395. }
  396. int
  397. GetBootDisk()
  398. {
  399. CHAR szTemp[MAXPATHLEN];
  400. // well, close enough...
  401. if (GetWindowsDirectory(szTemp, sizeof(szTemp))) {
  402. return szTemp[0] - 'A';
  403. } else {
  404. return 'a';
  405. }
  406. }
  407. //
  408. // IsCDROM() - determine if a drive is a CDROM drive
  409. //
  410. // iDrive drive index (0=A, 1=B, ...)
  411. //
  412. // return TRUE/FALSE
  413. //
  414. WORD
  415. APIENTRY
  416. IsCDRomDrive(
  417. INT iDrive
  418. )
  419. {
  420. if (rgiDriveType[iDrive] == DRIVE_CDROM)
  421. return (TRUE);
  422. return (FALSE);
  423. }
  424. // this is called for every drive at init time so it must
  425. // be sure to not trigget things like the phantom B: drive support
  426. //
  427. // iDrive is a zero based drive number (0 = A, 1 = B)
  428. WORD
  429. APIENTRY
  430. IsNetDrive(
  431. INT iDrive
  432. )
  433. {
  434. INT err;
  435. CHAR szDrive[3];
  436. CHAR szConn[64]; // this really should be WNBD_MAX_LENGTH
  437. // but this change would have to be many everywhere
  438. szDrive[0] = (CHAR)(iDrive+'A');
  439. szDrive[1] = ':';
  440. szDrive[2] = (CHAR)0;
  441. if (IsCDRomDrive(iDrive)) // this is bogus... move this out
  442. return 0;
  443. err = WFGetConnection(szDrive, szConn, TRUE);
  444. if (err == WN_SUCCESS)
  445. return 1;
  446. if (err == WN_CONNECTION_CLOSED || err == WN_DEVICE_ERROR)
  447. return 2;
  448. return 0;
  449. }
  450. BOOL
  451. APIENTRY
  452. IsRemovableDrive(
  453. INT iDrive
  454. )
  455. {
  456. return DriveType(iDrive) == DRIVE_REMOVABLE;
  457. }
  458. BOOL
  459. APIENTRY
  460. IsRemoteDrive(
  461. INT iDrive
  462. )
  463. {
  464. return DriveType(iDrive) == DRIVE_REMOTE;
  465. }
  466. // iDrive zero based drive number (A = 0)
  467. BOOL
  468. APIENTRY
  469. IsRamDrive(
  470. INT iDrive
  471. )
  472. {
  473. return DriveType(iDrive) == DRIVE_RAMDISK;
  474. }
  475. // get interesting stuff about a drive
  476. //
  477. // zero based drive numbers (0 = A, 1 = B)
  478. //
  479. DWORD
  480. APIENTRY
  481. GetClusterInfo(
  482. WORD drive
  483. )
  484. {
  485. UNREFERENCED_PARAMETER(drive);
  486. return 0;
  487. }
  488. BOOL
  489. APIENTRY
  490. IsValidDisk(
  491. INT iDrive
  492. )
  493. {
  494. if (apVolInfo[iDrive] == NULL)
  495. FillVolumeInfo(iDrive);
  496. return (apVolInfo[iDrive] != NULL);
  497. }
  498. VOID
  499. APIENTRY
  500. GetVolShare(
  501. WORD wDrive,
  502. LPSTR szVolShare
  503. )
  504. {
  505. CHAR szDrive[5];
  506. szVolShare[0] = TEXT('\0');
  507. lstrcpy(szVolShare, "Objects");
  508. }
  509. /*--------------------------------------------------------------------------*/
  510. /* */
  511. /* IsLFNSelected() - */
  512. /* */
  513. /*--------------------------------------------------------------------------*/
  514. BOOL
  515. APIENTRY
  516. IsLFNSelected()
  517. {
  518. HWND hwndActive;
  519. BOOL fDir;
  520. LPSTR p;
  521. hwndActive = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L);
  522. p = (LPSTR)SendMessage(hwndActive, FS_GETSELECTION, 2, (LPARAM)&fDir);
  523. if (p) {
  524. LocalFree((HANDLE)p);
  525. }
  526. return (fDir);
  527. }
  528. /*--------------------------------------------------------------------------*/
  529. /* */
  530. /* GetSelection() - */
  531. // caller must free lpstr returned.
  532. /* */
  533. /*--------------------------------------------------------------------------*/
  534. LPSTR
  535. APIENTRY
  536. GetSelection(
  537. INT iSelType
  538. )
  539. {
  540. HWND hwndActive;
  541. hwndActive = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L);
  542. return (LPSTR)SendMessage(hwndActive,FS_GETSELECTION, (WPARAM)iSelType, 0L);
  543. }
  544. //
  545. // in:
  546. // pFrom pointer that is used as start of selection search.
  547. // on subsequent calls pass in the previous non NULL
  548. // return value
  549. //
  550. // out:
  551. // pTo buffer that receives the next file in the list
  552. // for non NULL return
  553. //
  554. // returns:
  555. // NULL if no more files in this list (szFile) is undefined
  556. // pointer to be passed to subsequent calls to this function
  557. // to enumerate thorough the file list
  558. //
  559. LPSTR
  560. APIENTRY
  561. GetNextFile(
  562. LPSTR pFrom,
  563. LPSTR pTo,
  564. INT cbMax
  565. )
  566. {
  567. INT i;
  568. ENTER("GetNextFile");
  569. PRINT(BF_PARMTRACE, "IN: pFrom=%s", pFrom);
  570. if (!pFrom)
  571. return NULL;
  572. /* Skip over leading spaces and commas. */
  573. while (*pFrom && (*pFrom == ' ' || *pFrom == ','))
  574. pFrom = (LPSTR)AnsiNext(pFrom);
  575. if (!*pFrom)
  576. return (NULL);
  577. if (*pFrom == '\"') {
  578. pFrom = (LPSTR)AnsiNext(pFrom);
  579. /* Find the next quote */
  580. for (i=0; *pFrom && *pFrom != '\"';) {
  581. if (*pFrom == '^') {
  582. pFrom = (LPSTR)AnsiNext(pFrom);
  583. if (!*pFrom)
  584. break;
  585. }
  586. if (i < cbMax - 1) {
  587. i++;
  588. if (IsDBCSLeadByte(*pTo++ = *pFrom++)) {
  589. i++;
  590. *pTo++ = *pFrom++;
  591. }
  592. }
  593. }
  594. pFrom = (LPSTR)AnsiNext(pFrom);
  595. } else {
  596. /* Find the next space or comma. */
  597. for (i=0; *pFrom && *pFrom != ' ' && *pFrom != ',';) {
  598. if (*pFrom == '^') {
  599. pFrom = (LPSTR)AnsiNext(pFrom);
  600. if (!*pFrom)
  601. break;
  602. }
  603. if (i < cbMax - 1) {
  604. i++;
  605. if (IsDBCSLeadByte(*pTo++ = *pFrom++)) {
  606. i++;
  607. *pTo++ = *pFrom++;
  608. }
  609. }
  610. }
  611. }
  612. *pTo = TEXT('\0');
  613. PRINT(BF_PARMTRACE, pTo ? "OUT: pTo=%s" : "OUT: pTo=NULL", pTo);
  614. LEAVE("GetNextFile");
  615. return (pFrom);
  616. }
  617. // sets the DOS current directory based on the currently active window
  618. VOID
  619. APIENTRY
  620. SetWindowDirectory()
  621. {
  622. CHAR szTemp[MAXPATHLEN];
  623. GetSelectedDirectory(0, szTemp);
  624. FixAnsiPathForDos(szTemp);
  625. SheChangeDir(szTemp);
  626. }
  627. /*--------------------------------------------------------------------------*/
  628. /* */
  629. /* SetDlgDirectory() - */
  630. /* */
  631. /*--------------------------------------------------------------------------*/
  632. /* Sets the IDD_DIR field of 'hDlg' to whatever the active window says is the
  633. * active directory.
  634. *
  635. * this does not really change the DOS current directory
  636. */
  637. VOID
  638. APIENTRY
  639. SetDlgDirectory(
  640. HWND hDlg,
  641. PSTR pszPath
  642. )
  643. {
  644. HDC hDC;
  645. INT dx;
  646. RECT rc;
  647. HWND hDlgItem;
  648. HANDLE hFont;
  649. CHAR szPath[MAXPATHLEN+5];
  650. CHAR szTemp[MAXPATHLEN+20];
  651. ENTER("SetDlgDirectory");
  652. if (pszPath)
  653. lstrcpy(szPath, pszPath);
  654. else
  655. GetSelectedDirectory(0, szPath);
  656. /* Make sure that the current directory fits inside the static text field. */
  657. hDlgItem = GetDlgItem(hDlg, IDD_DIR);
  658. GetClientRect(hDlgItem, &rc);
  659. if (LoadString(hAppInstance, IDS_CURDIRIS, szMessage, sizeof(szMessage))) {
  660. hDC = GetDC(hDlg);
  661. hFont = (HANDLE)SendMessage(hDlgItem, WM_GETFONT, 0, 0L);
  662. if (hFont = SelectObject(hDC, hFont)) {
  663. MGetTextExtent(hDC, szMessage, lstrlen(szMessage), &dx, NULL);
  664. CompactPath(hDC, szPath, (WORD)(rc.right-rc.left-dx));
  665. }
  666. SelectObject(hDC, hFont);
  667. ReleaseDC(hDlg, hDC);
  668. wsprintf(szTemp, szMessage, (LPSTR)szPath);
  669. SetDlgItemText(hDlg, IDD_DIR, szTemp);
  670. }
  671. LEAVE("SetDlgDirectory");
  672. }
  673. /*--------------------------------------------------------------------------*/
  674. /* */
  675. /* WritePrivateProfileBool() - */
  676. /* */
  677. /*--------------------------------------------------------------------------*/
  678. VOID
  679. APIENTRY
  680. WritePrivateProfileBool(
  681. LPSTR szKey,
  682. BOOL bParam
  683. )
  684. {
  685. CHAR szBool[6];
  686. wsprintf(szBool, "%d", bParam);
  687. WritePrivateProfileString(szSettings, szKey, szBool, szTheINIFile);
  688. }
  689. /*--------------------------------------------------------------------------*/
  690. /* */
  691. /* WFQueryAbort() - */
  692. /* */
  693. /*--------------------------------------------------------------------------*/
  694. BOOL
  695. APIENTRY
  696. WFQueryAbort()
  697. {
  698. MSG msg;
  699. while (PeekMessage(&msg, NULL, 0, 0, TRUE)) {
  700. if (!IsDialogMessage(hdlgProgress, &msg))
  701. DispatchMessage(&msg);
  702. }
  703. return (bUserAbort);
  704. }
  705. /*--------------------------------------------------------------------------*/
  706. /* */
  707. /* IsWild() - */
  708. /* */
  709. /*--------------------------------------------------------------------------*/
  710. /* Returns TRUE iff the path contains * or ? */
  711. BOOL
  712. APIENTRY
  713. IsWild(
  714. LPSTR lpszPath
  715. )
  716. {
  717. while (*lpszPath) {
  718. if (*lpszPath == '?' || *lpszPath == '*')
  719. return (TRUE);
  720. lpszPath = AnsiNext(lpszPath);
  721. }
  722. return (FALSE);
  723. }
  724. /*--------------------------------------------------------------------------*/
  725. /* */
  726. /* CheckSlashies() - */
  727. /* */
  728. /*--------------------------------------------------------------------------*/
  729. /* Replaces frontslashes (evil) with backslashes (good). */
  730. VOID
  731. APIENTRY
  732. CheckSlashies(
  733. LPSTR lpT
  734. )
  735. {
  736. while (*lpT) {
  737. if (*lpT == '/')
  738. *lpT = '\\';
  739. lpT = AnsiNext(lpT);
  740. }
  741. }
  742. /*--------------------------------------------------------------------------*/
  743. /* */
  744. /* AddBackslash() - */
  745. /* */
  746. /*--------------------------------------------------------------------------*/
  747. /* Ensures that a path ends with a backslash. */
  748. VOID
  749. APIENTRY
  750. AddBackslash(
  751. LPSTR lpszPath
  752. )
  753. {
  754. ENTER("AddBackslash");
  755. PRINT(BF_PARMTRACE, "IN: lpszPath=%s", lpszPath);
  756. if (*AnsiPrev(lpszPath,lpszPath+lstrlen(lpszPath)) != '\\')
  757. lstrcat(lpszPath, "\\");
  758. PRINT(BF_PARMTRACE, "OUT: lpszPath=%s", lpszPath);
  759. LEAVE("AddBackslash");
  760. }
  761. /*--------------------------------------------------------------------------*/
  762. /* */
  763. /* StripBackslash() - */
  764. /* */
  765. /*--------------------------------------------------------------------------*/
  766. /* Removes a trailing backslash from a proper directory name UNLESS it is
  767. * the root directory. Assumes a fully qualified directory path.
  768. */
  769. VOID
  770. APIENTRY
  771. StripBackslash(
  772. LPSTR lpszPath
  773. )
  774. {
  775. register WORD len;
  776. len = lstrlen(lpszPath) - (IsDBCSLeadByte(*AnsiPrev(lpszPath,lpszPath+lstrlen(lpszPath))) ? 2 : 1);
  777. if ((len == 2) || (lpszPath[len] != '\\'))
  778. return;
  779. lpszPath[len] = TEXT('\0');
  780. }
  781. /*--------------------------------------------------------------------------*/
  782. /* */
  783. /* StripFilespec() - */
  784. /* */
  785. /*--------------------------------------------------------------------------*/
  786. /* Remove the filespec portion from a path (including the backslash). */
  787. VOID
  788. APIENTRY
  789. StripFilespec(
  790. LPSTR lpszPath
  791. )
  792. {
  793. LPSTR p;
  794. p = lpszPath + lstrlen(lpszPath);
  795. while ((*p != '\\') && (*p != ':') && (p != lpszPath))
  796. p = AnsiPrev(lpszPath, p);
  797. if (*p == ':')
  798. p++;
  799. /* Don't strip backslash from root directory entry. */
  800. if (p != lpszPath) {
  801. if ((*p == '\\') && (*(p-1) == ':'))
  802. p++;
  803. } else
  804. p++;
  805. *p = TEXT('\0');
  806. }
  807. /*--------------------------------------------------------------------------*/
  808. /* */
  809. /* StripPath() - */
  810. /* */
  811. /*--------------------------------------------------------------------------*/
  812. /* Extract only the filespec portion from a path. */
  813. VOID
  814. APIENTRY
  815. StripPath(
  816. LPSTR lpszPath
  817. )
  818. {
  819. LPSTR p;
  820. ENTER("StripPath");
  821. PRINT(BF_PARMTRACE, "IN: lpszPath=%s", lpszPath);
  822. p = lpszPath + lstrlen(lpszPath);
  823. while ((*p != '\\') && (*p != ':') && (p != lpszPath))
  824. p = AnsiPrev(lpszPath, p);
  825. if (p != lpszPath || *p == '\\')
  826. p++;
  827. if (p != lpszPath)
  828. lstrcpy(lpszPath, p);
  829. PRINT(BF_PARMTRACE, "OUT: lpszPath=%s", lpszPath);
  830. LEAVE("StripPath");
  831. }
  832. /*--------------------------------------------------------------------------*/
  833. /* */
  834. /* GetExtension() - */
  835. /* */
  836. /*--------------------------------------------------------------------------*/
  837. /* Returns the extension part of a filename. */
  838. LPSTR
  839. APIENTRY
  840. GetExtension(
  841. LPSTR pszFile
  842. )
  843. {
  844. PSTR p, pSave = NULL;
  845. p = pszFile;
  846. while (*p) {
  847. if (*p == '.')
  848. pSave = p;
  849. p = (LPSTR)AnsiNext(p);
  850. }
  851. if (!pSave)
  852. return (p);
  853. return (LPSTR)AnsiNext(pSave);
  854. }
  855. /*--------------------------------------------------------------------------*/
  856. /* */
  857. /* FindExtensionInList() - */
  858. /* */
  859. /*--------------------------------------------------------------------------*/
  860. /* Returns TRUE if 'lpszExt' is somewhere in 'pszList'. */
  861. BOOL
  862. APIENTRY
  863. FindExtensionInList(
  864. LPSTR pszExt,
  865. LPSTR pszList
  866. )
  867. {
  868. LPSTR p2;
  869. CHAR ch;
  870. while (*pszList) {
  871. /* Move to the next item in the list. */
  872. while ((*pszList) && (*pszList == ' '))
  873. pszList = (LPSTR)AnsiNext(pszList);
  874. if (!*pszList)
  875. break;
  876. /* NULL-terminate this item. */
  877. p2 = (LPSTR)AnsiNext(pszList);
  878. while ((*p2) && (*p2 != ' '))
  879. p2 = (LPSTR)AnsiNext(p2);
  880. ch = *p2;
  881. *p2 = TEXT('\0');
  882. if (!lstrcmpi(pszExt, pszList)) {
  883. *p2 = ch;
  884. return (TRUE);
  885. }
  886. *p2 = ch;
  887. pszList = p2;
  888. }
  889. return (FALSE);
  890. }
  891. /*--------------------------------------------------------------------------*/
  892. /* */
  893. /* MyMessageBox() - */
  894. /* */
  895. /*--------------------------------------------------------------------------*/
  896. INT
  897. APIENTRY
  898. MyMessageBox(
  899. HWND hWnd,
  900. WORD idTitle,
  901. WORD idMessage,
  902. WORD wStyle
  903. )
  904. {
  905. CHAR szTemp[MAXMESSAGELEN];
  906. HWND hwndT;
  907. LoadString(hAppInstance, idTitle, szTitle, sizeof(szTitle));
  908. if (idMessage < 32) {
  909. LoadString(hAppInstance, IDS_UNKNOWNMSG, szTemp, sizeof(szTemp));
  910. wsprintf(szMessage, szTemp, idMessage);
  911. } else
  912. LoadString(hAppInstance, idMessage, szMessage, sizeof(szMessage));
  913. if (hWnd)
  914. hwndT = GetLastActivePopup(hWnd);
  915. else
  916. hwndT = hWnd;
  917. return MessageBox(hwndT, szMessage, szTitle, wStyle | MB_TASKMODAL);
  918. }
  919. /*--------------------------------------------------------------------------*/
  920. /* */
  921. /* ExecProgram() - */
  922. /* */
  923. /* all strings are OEM */
  924. /*--------------------------------------------------------------------------*/
  925. /* Returns 0 for success. Otherwise returns a IDS_ string code. */
  926. WORD
  927. APIENTRY
  928. ExecProgram(
  929. LPSTR lpPath,
  930. LPSTR lpParms,
  931. LPSTR lpDir,
  932. BOOL bLoadIt
  933. )
  934. {
  935. WORD ret;
  936. INT iCurCount;
  937. INT i;
  938. HCURSOR hCursor;
  939. ENTER("ExecProgram");
  940. ret = 0;
  941. hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  942. iCurCount = ShowCursor(TRUE) - 1;
  943. /* open the object
  944. */
  945. if (lpPath)
  946. OemToAnsi(lpPath, lpPath);
  947. if (lpParms)
  948. OemToAnsi(lpParms, lpParms);
  949. if (lpDir)
  950. OemToAnsi(lpDir, lpDir);
  951. // Shell Execute takes ansi string.
  952. //
  953. ret = (WORD)RealShellExecute(hwndFrame, NULL, lpPath, lpParms, lpDir, NULL, NULL, NULL, (WORD)(bLoadIt ? SW_SHOWMINNOACTIVE : SW_SHOWNORMAL), NULL);
  954. DosResetDTAAddress(); // undo any bad things COMMDLG did
  955. if (lpPath)
  956. AnsiToOem(lpPath, lpPath);
  957. if (lpParms)
  958. AnsiToOem(lpParms, lpParms);
  959. if (lpDir)
  960. AnsiToOem(lpDir, lpDir);
  961. switch (ret) {
  962. case 0:
  963. case 8:
  964. ret = IDS_NOMEMORYMSG;
  965. break;
  966. case 2:
  967. ret = IDS_FILENOTFOUNDMSG;
  968. break;
  969. case 3:
  970. case 5: // access denied
  971. ret = IDS_BADPATHMSG;
  972. break;
  973. case 4:
  974. ret = IDS_MANYOPENFILESMSG;
  975. break;
  976. case 10:
  977. ret = IDS_NEWWINDOWSMSG;
  978. break;
  979. case 12:
  980. ret = IDS_OS2APPMSG;
  981. break;
  982. case 15:
  983. /* KERNEL has already put up a messagebox for this one. */
  984. ret = 0;
  985. break;
  986. case 16:
  987. ret = IDS_MULTIPLEDSMSG;
  988. break;
  989. case 18:
  990. ret = IDS_PMODEONLYMSG;
  991. break;
  992. case 19:
  993. ret = IDS_COMPRESSEDEXE;
  994. break;
  995. case 20:
  996. ret = IDS_INVALIDDLL;
  997. break;
  998. case SE_ERR_SHARE:
  999. ret = IDS_SHAREERROR;
  1000. break;
  1001. case SE_ERR_ASSOCINCOMPLETE:
  1002. ret = IDS_ASSOCINCOMPLETE;
  1003. break;
  1004. case SE_ERR_DDETIMEOUT:
  1005. case SE_ERR_DDEFAIL:
  1006. case SE_ERR_DDEBUSY:
  1007. ret = IDS_DDEFAIL;
  1008. break;
  1009. case SE_ERR_NOASSOC:
  1010. ret = IDS_NOASSOCMSG;
  1011. break;
  1012. default:
  1013. if (ret < 32)
  1014. goto EPExit;
  1015. if (bMinOnRun && !bLoadIt)
  1016. ShowWindow(hwndFrame, SW_SHOWMINNOACTIVE);
  1017. ret = 0;
  1018. }
  1019. EPExit:
  1020. i = ShowCursor(FALSE);
  1021. #if 0
  1022. /* Make sure that the cursor count is still balanced. */
  1023. if (i != iCurCount)
  1024. ShowCursor(TRUE);
  1025. #endif
  1026. SetCursor(hCursor);
  1027. PRINT(BF_PARMTRACE, "OUT: ret=%ud", ret);
  1028. LEAVE("ExecProgram");
  1029. return ret;
  1030. }
  1031. /*--------------------------------------------------------------------------*/
  1032. /* */
  1033. /* IsProgramFile() - */
  1034. /* */
  1035. /*--------------------------------------------------------------------------*/
  1036. /* Returns TRUE is the Path points to a file which has one of the extentions
  1037. * listed in the "Programs=" portions of WIN.INI.
  1038. */
  1039. BOOL
  1040. APIENTRY
  1041. IsProgramFile(
  1042. LPSTR lpszPath
  1043. )
  1044. {
  1045. LPSTR szExt;
  1046. CHAR szTemp[MAXPATHLEN];
  1047. /* Move the string into our own DS. */
  1048. lstrcpy(szTemp, lpszPath);
  1049. /* Get the file's extension. */
  1050. StripPath(szTemp);
  1051. szExt = GetExtension(szTemp);
  1052. if (!*szExt) {
  1053. /* The specified path didn't have an extention. It can't be a program. */
  1054. return (FALSE);
  1055. }
  1056. return FindExtensionInList(szExt, szPrograms);
  1057. }
  1058. /*--------------------------------------------------------------------------*/
  1059. /* */
  1060. /* IsDocument() - */
  1061. /* */
  1062. /*--------------------------------------------------------------------------*/
  1063. /* Returns TRUE is the Path points to a file which has one of the extentions
  1064. * listed in the "Documents=" portions of WIN.INI or one which has an Association.
  1065. */
  1066. BOOL
  1067. APIENTRY
  1068. IsDocument(
  1069. LPSTR lpszPath
  1070. )
  1071. {
  1072. LPSTR szExt;
  1073. CHAR szTemp[MAXPATHLEN];
  1074. /* Move the string into our own DS. */
  1075. lstrcpy(szTemp, lpszPath);
  1076. /* Get the file's extension. */
  1077. StripPath(szTemp);
  1078. szExt = GetExtension(szTemp);
  1079. if (!*szExt) {
  1080. /* The specified path didn't have an extention. It can't be a program. */
  1081. return (FALSE);
  1082. }
  1083. return FindExtensionInList(szExt, szDocuments);
  1084. }