/****************************************************************************/ /* */ /* WFUTIL.C - */ /* */ /* Windows File System String Utility Functions */ /* */ /****************************************************************************/ #include "winfile.h" #include "lfn.h" #include "winnet.h" #include "wnetcaps.h" // WNetGetCaps() #include "stdlib.h" int rgiDriveType[26]; PSTR CurDirCache[26]; // cache GetDriveType calls for speed INT DriveType( INT iDrive ) { if (rgiDriveType[iDrive] != -1) return rgiDriveType[iDrive]; return rgiDriveType[iDrive] = MGetDriveType(iDrive); } VOID InvalidateDriveType() { INT i; for (i = 0; i < 26; i++) rgiDriveType[i] = -1; } // iDrive zero based drive number (0 = A, 1 = B) // returns: // TRUE we have it saved pszPath gets path // FALSE we don't have it saved BOOL APIENTRY GetSavedDirectory( INT iDrive, PSTR pszPath ) { if (CurDirCache[iDrive]) { lstrcpy(pszPath, CurDirCache[iDrive]); return TRUE; } else return FALSE; } VOID APIENTRY SaveDirectory( PSTR pszPath ) { INT i; i = DRIVEID(pszPath); if (CurDirCache[i]) LocalFree((HANDLE)CurDirCache[i]); CurDirCache[i] = (PSTR)LocalAlloc(LPTR, lstrlen(pszPath)+1); if (CurDirCache[i]) lstrcpy(CurDirCache[i], pszPath); } /* * GetSelectedDrive() - * * Get the selected drive from the currently active window * * should be in wfutil.c */ INT APIENTRY GetSelectedDrive() { HWND hwnd; hwnd = (HWND)SendMessage(hwndMDIClient,WM_MDIGETACTIVE,0,0L); return (INT)SendMessage(hwnd,FS_GETDRIVE,0,0L) - (INT)'A'; } /* * GetSelectedDirectory() - * * Gets the directory selected for the drive. uses the windows * z-order to give precidence to windows higher in the order. * * works like GetCurrentDirectory() except it looks through * the window list for directories first (and returns ANSI) * * returns: * lpDir ANSI string of current dir */ VOID APIENTRY GetSelectedDirectory( WORD iDrive, PSTR pszDir ) { HWND hwnd; WORD iDriveT; if (iDrive) { for (hwnd = GetWindow(hwndMDIClient,GW_CHILD); hwnd; hwnd = GetWindow(hwnd,GW_HWNDNEXT)) { iDriveT = (WORD)SendMessage(hwnd,FS_GETDRIVE,0,0L); if (iDrive == (WORD)(iDriveT - 'A' + 1)) goto hwndfound; } if (!GetSavedDirectory(iDrive - 1, pszDir)) { SheGetDir(iDrive,pszDir); OemToCharBuff(pszDir,pszDir, _MAX_PATH); } return; } else hwnd = (HWND)SendMessage(hwndMDIClient,WM_MDIGETACTIVE,0,0L); hwndfound: SendMessage(hwnd,FS_GETDIRECTORY,MAXPATHLEN,(LPARAM)pszDir); StripBackslash(pszDir); } // avoid confusion in DOSs upper case mapping by converting to // upper case before passing down to dos VOID APIENTRY FixAnsiPathForDos( LPSTR szPath ) { if (GetNameType(szPath) == FILE_83_CI) AnsiUpper(szPath); AnsiToOem(szPath, szPath); } // refresh a MDI child window (works for any type of mdi child) VOID APIENTRY RefreshWindow( HWND hwndActive ) { HWND hwndTree, hwndDir; LPARAM lParam; CHAR szDir[MAXPATHLEN]; INT iDrive; cDrives = UpdateDriveList(); // updates rgiDrive[] InitDriveBitmaps(); // make sure the thing is still there (floppy drive, net drive) iDrive = (INT)GetWindowLong(hwndActive, GWL_TYPE); if ((iDrive >= 0) && !CheckDrive(hwndActive, iDrive)) return; // update the dir part first so tree can steal later if (hwndDir = HasDirWindow(hwndActive)) SendMessage(hwndDir, FS_CHANGEDISPLAY, CD_PATH, 0L); if (hwndTree = HasTreeWindow(hwndActive)) { // remember the current directory SendMessage(hwndActive, FS_GETDIRECTORY, sizeof(szDir), (LPARAM)szDir); // update the drives windows SendMessage(hwndActive, FS_CHANGEDRIVES, 0, 0L); if (IsValidDisk(szDir[0] - 'A')) lParam = (LPARAM)szDir; else lParam = 0; // update the tree SendMessage(hwndTree, TC_SETDRIVE, MAKEWORD(FALSE, TRUE), lParam); } if (hwndActive == hwndSearch) SendMessage(hwndActive, FS_CHANGEDISPLAY, CD_PATH, 0L); } VOID APIENTRY CheckEscapes( LPSTR szFile ) { CHAR szT[MAXPATHLEN]; CHAR *p, *pT; for (p = szFile; *p; p = (LPSTR)AnsiNext(p)) { switch (*p) { case ' ': case ',': case ';': case '^': case '"': { // this path contains an annoying character lstrcpy(szT,szFile); p = szFile; *p++ = '"'; for (pT = szT; *pT; ) { if (*pT == '^' || *pT == '"') *p++ = '^'; if (IsDBCSLeadByte(*p++ = *pT++)) *p++ = *pT++; } *p++ = '"'; *p = 0; return; } } } } HWND APIENTRY GetRealParent( HWND hwnd ) { // run up the parent chain until you find a hwnd // that doesn't have WS_CHILD set while (GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD) hwnd = (HWND)GetWindowLongPtr(hwnd, GWLP_HWNDPARENT); return hwnd; } VOID APIENTRY WFHelp( HWND hwnd ) { if (!WinHelp(hwnd, szWinObjHelp, HELP_CONTEXT, dwContext)) { MyMessageBox(hwnd, IDS_WINFILE, IDS_WINHELPERR, MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL); } } BOOL APIENTRY IsLastWindow() { HWND hwnd; INT count; count = 0; // count all non title/search windows to see if close is allowed for (hwnd = GetWindow(hwndMDIClient, GW_CHILD); hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT)) if (!GetWindow(hwnd, GW_OWNER) && ((INT)GetWindowLong(hwnd, GWL_TYPE) >= 0)) count++; return count == 1; } // get connection information including disconnected drives // // in: // lpDev device name "A:" "LPT1:", etc. // fClosed if FALSE closed or error drives will be converted to // WN_SUCCESS return codes. if TRUE return not connected // and error state values (ie, the caller knows about not // connected and error state drives) // out: // lpPath filled with net name if return is WN_SUCCESS (or not connected/error) // returns: // WN_* error code WORD APIENTRY WFGetConnection( LPSTR lpDev, LPSTR lpPath, BOOL fClosed ) { DWORD cb; UINT err; UINT caps; cb = 64; caps = WNetGetCaps(WNNC_CONNECTION); if (caps & WNNC_CON_GETCONNECTIONS) err = WNetGetConnection(lpDev,lpPath,&cb); else return WN_NOT_CONNECTED; if (err == WN_NOT_CONNECTED && !(caps & WNNC_CON_RESTORECONNECTION)) { if (GetProfileString(szNetwork,lpDev,szNULL,lpPath,64)) err = WN_CONNECTION_CLOSED; } if (!fClosed) if (err == WN_CONNECTION_CLOSED || err == WN_DEVICE_ERROR) err = WN_SUCCESS; return (WORD)err; } // returns the number of this MDI window as well as returning // the text with the number stripped off // // returns: // 0 this title doesn't have a number // > 0 the title number // szTitle the title with the number stripped off INT APIENTRY GetMDIWindowText( HWND hWnd, LPSTR szTitle, INT size ) { LPSTR lp, lpLast; ENTER("GetMDIWindowText"); GetWindowText(hWnd, szTitle, size); lpLast = NULL; for (lp = szTitle; *lp; lp = AnsiNext(lp)) if (*lp == ':') lpLast = lp; if (lpLast) { *lpLast++ = 0; PRINT(BF_PARMTRACE, "OUT: szTitle=%s", szTitle); PRINT(BF_PARMTRACE, "OUT: window#=%s", lpLast); LEAVE("GetMDIWindowText"); return atoi(lpLast); // return the window number } else { TRACE(BF_PARMTRACE, "OUT: window#=0"); LEAVE("GetMDIWindowText"); return 0; // no number on this } } // set the MDI window text and add a ":#" on the end if // there is another window with the same title. this is to // avoid confusion when there are multiple MDI children // with the same title. be sure to use GetMDIWindowText to // strip off the number stuff. VOID APIENTRY SetMDIWindowText( HWND hWnd, LPSTR szTitle ) { CHAR szTemp[MAXPATHLEN]; CHAR szNumber[20]; HWND hwnd; INT num, max_num; ENTER("SetMDIWindowText"); PRINT(BF_PARMTRACE, "hWnd=%lx", hWnd); PRINT(BF_PARMTRACE, "IN: szTitle=%s", szTitle); max_num = 0; for (hwnd = GetWindow(hwndMDIClient, GW_CHILD); hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT)) { num = GetMDIWindowText(hwnd, szTemp, sizeof(szTemp)); if (!lstrcmp(szTemp, szTitle)) { if (hwnd == hWnd) continue; if (!num) { lstrcat(szTemp, ":1"); // if (wTextAttribs & TA_LOWERCASE) // AnsiLower(szTemp); SetWindowText(hwnd, szTemp); num = 1; } max_num = max(max_num, num); } } if (max_num) { wsprintf(szNumber, ":%d", max_num+1); lstrcat(szTitle, szNumber); } // if (wTextAttribs & TA_LOWERCASE) // AnsiLower(szTitle); SetWindowText(hWnd, szTitle); PRINT(BF_PARMTRACE, "OUT: szTitle=%s", szTitle); LEAVE("SetMDIWindowText"); } #define ISDIGIT(c) ((c) >= '0' && (c) <= '9') #ifdef INLIBRARY INT APIENTRY atoi( LPSTR sz ) { INT n = 0; BOOL bNeg = FALSE; if (*sz == '-') { bNeg = TRUE; sz++; } while (ISDIGIT(*sz)) { n *= 10; n += *sz - '0'; sz++; } return bNeg ? -n : n; } #endif // fills in rgiDrive[] and returns the number of drives INT APIENTRY UpdateDriveList() { INT i, cRealDrives = 0; DWORD dwDrives; dwDrives = GetLogicalDrives(); for (i = 0; i < 26; i++) { if ((1 << i) & dwDrives) { rgiDrive[cRealDrives++] = i; rgiDriveType[i] = MGetDriveType(i); } else { rgiDrive[i] = 0; rgiDriveType[i] = -1; // invalidate the drivetype } if (apVolInfo[i]) { // sothat volinfo is refreshed LocalFree(apVolInfo[i]); apVolInfo[i] = NULL; } } return cRealDrives; } int GetBootDisk() { CHAR szTemp[MAXPATHLEN]; // well, close enough... if (GetWindowsDirectory(szTemp, sizeof(szTemp))) { return szTemp[0] - 'A'; } else { return 'a'; } } // // IsCDROM() - determine if a drive is a CDROM drive // // iDrive drive index (0=A, 1=B, ...) // // return TRUE/FALSE // WORD APIENTRY IsCDRomDrive( INT iDrive ) { if (rgiDriveType[iDrive] == DRIVE_CDROM) return (TRUE); return (FALSE); } // this is called for every drive at init time so it must // be sure to not trigget things like the phantom B: drive support // // iDrive is a zero based drive number (0 = A, 1 = B) WORD APIENTRY IsNetDrive( INT iDrive ) { INT err; CHAR szDrive[3]; CHAR szConn[64]; // this really should be WNBD_MAX_LENGTH // but this change would have to be many everywhere szDrive[0] = (CHAR)(iDrive+'A'); szDrive[1] = ':'; szDrive[2] = (CHAR)0; if (IsCDRomDrive(iDrive)) // this is bogus... move this out return 0; err = WFGetConnection(szDrive, szConn, TRUE); if (err == WN_SUCCESS) return 1; if (err == WN_CONNECTION_CLOSED || err == WN_DEVICE_ERROR) return 2; return 0; } BOOL APIENTRY IsRemovableDrive( INT iDrive ) { return DriveType(iDrive) == DRIVE_REMOVABLE; } BOOL APIENTRY IsRemoteDrive( INT iDrive ) { return DriveType(iDrive) == DRIVE_REMOTE; } // iDrive zero based drive number (A = 0) BOOL APIENTRY IsRamDrive( INT iDrive ) { return DriveType(iDrive) == DRIVE_RAMDISK; } // get interesting stuff about a drive // // zero based drive numbers (0 = A, 1 = B) // DWORD APIENTRY GetClusterInfo( WORD drive ) { UNREFERENCED_PARAMETER(drive); return 0; } BOOL APIENTRY IsValidDisk( INT iDrive ) { if (apVolInfo[iDrive] == NULL) FillVolumeInfo(iDrive); return (apVolInfo[iDrive] != NULL); } VOID APIENTRY GetVolShare( WORD wDrive, LPSTR szVolShare ) { CHAR szDrive[5]; szVolShare[0] = TEXT('\0'); lstrcpy(szVolShare, "Objects"); } /*--------------------------------------------------------------------------*/ /* */ /* IsLFNSelected() - */ /* */ /*--------------------------------------------------------------------------*/ BOOL APIENTRY IsLFNSelected() { HWND hwndActive; BOOL fDir; LPSTR p; hwndActive = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L); p = (LPSTR)SendMessage(hwndActive, FS_GETSELECTION, 2, (LPARAM)&fDir); if (p) { LocalFree((HANDLE)p); } return (fDir); } /*--------------------------------------------------------------------------*/ /* */ /* GetSelection() - */ // caller must free lpstr returned. /* */ /*--------------------------------------------------------------------------*/ LPSTR APIENTRY GetSelection( INT iSelType ) { HWND hwndActive; hwndActive = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L); return (LPSTR)SendMessage(hwndActive,FS_GETSELECTION, (WPARAM)iSelType, 0L); } // // in: // pFrom pointer that is used as start of selection search. // on subsequent calls pass in the previous non NULL // return value // // out: // pTo buffer that receives the next file in the list // for non NULL return // // returns: // NULL if no more files in this list (szFile) is undefined // pointer to be passed to subsequent calls to this function // to enumerate thorough the file list // LPSTR APIENTRY GetNextFile( LPSTR pFrom, LPSTR pTo, INT cbMax ) { INT i; ENTER("GetNextFile"); PRINT(BF_PARMTRACE, "IN: pFrom=%s", pFrom); if (!pFrom) return NULL; /* Skip over leading spaces and commas. */ while (*pFrom && (*pFrom == ' ' || *pFrom == ',')) pFrom = (LPSTR)AnsiNext(pFrom); if (!*pFrom) return (NULL); if (*pFrom == '\"') { pFrom = (LPSTR)AnsiNext(pFrom); /* Find the next quote */ for (i=0; *pFrom && *pFrom != '\"';) { if (*pFrom == '^') { pFrom = (LPSTR)AnsiNext(pFrom); if (!*pFrom) break; } if (i < cbMax - 1) { i++; if (IsDBCSLeadByte(*pTo++ = *pFrom++)) { i++; *pTo++ = *pFrom++; } } } pFrom = (LPSTR)AnsiNext(pFrom); } else { /* Find the next space or comma. */ for (i=0; *pFrom && *pFrom != ' ' && *pFrom != ',';) { if (*pFrom == '^') { pFrom = (LPSTR)AnsiNext(pFrom); if (!*pFrom) break; } if (i < cbMax - 1) { i++; if (IsDBCSLeadByte(*pTo++ = *pFrom++)) { i++; *pTo++ = *pFrom++; } } } } *pTo = TEXT('\0'); PRINT(BF_PARMTRACE, pTo ? "OUT: pTo=%s" : "OUT: pTo=NULL", pTo); LEAVE("GetNextFile"); return (pFrom); } // sets the DOS current directory based on the currently active window VOID APIENTRY SetWindowDirectory() { CHAR szTemp[MAXPATHLEN]; GetSelectedDirectory(0, szTemp); FixAnsiPathForDos(szTemp); SheChangeDir(szTemp); } /*--------------------------------------------------------------------------*/ /* */ /* SetDlgDirectory() - */ /* */ /*--------------------------------------------------------------------------*/ /* Sets the IDD_DIR field of 'hDlg' to whatever the active window says is the * active directory. * * this does not really change the DOS current directory */ VOID APIENTRY SetDlgDirectory( HWND hDlg, PSTR pszPath ) { HDC hDC; INT dx; RECT rc; HWND hDlgItem; HANDLE L_hFont; CHAR szPath[MAXPATHLEN+5]; CHAR szTemp[MAXPATHLEN+20]; ENTER("SetDlgDirectory"); if (pszPath) lstrcpy(szPath, pszPath); else GetSelectedDirectory(0, szPath); /* Make sure that the current directory fits inside the static text field. */ hDlgItem = GetDlgItem(hDlg, IDD_DIR); GetClientRect(hDlgItem, &rc); if (LoadString(hAppInstance, IDS_CURDIRIS, szMessage, sizeof(szMessage))) { hDC = GetDC(hDlg); L_hFont = (HANDLE)SendMessage(hDlgItem, WM_GETFONT, 0, 0L); if (L_hFont = SelectObject(hDC, L_hFont)) { MGetTextExtent(hDC, szMessage, lstrlen(szMessage), &dx, NULL); CompactPath(hDC, szPath, (WORD)(rc.right-rc.left-dx)); } SelectObject(hDC, L_hFont); ReleaseDC(hDlg, hDC); wsprintf(szTemp, szMessage, (LPSTR)szPath); SetDlgItemText(hDlg, IDD_DIR, szTemp); } LEAVE("SetDlgDirectory"); } /*--------------------------------------------------------------------------*/ /* */ /* WritePrivateProfileBool() - */ /* */ /*--------------------------------------------------------------------------*/ VOID APIENTRY WritePrivateProfileBool( LPSTR szKey, BOOL bParam ) { CHAR szBool[6]; wsprintf(szBool, "%d", bParam); WritePrivateProfileString(szSettings, szKey, szBool, szTheINIFile); } /*--------------------------------------------------------------------------*/ /* */ /* WFQueryAbort() - */ /* */ /*--------------------------------------------------------------------------*/ BOOL APIENTRY WFQueryAbort() { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, TRUE)) { if (!IsDialogMessage(hdlgProgress, &msg)) DispatchMessage(&msg); } return (bUserAbort); } /*--------------------------------------------------------------------------*/ /* */ /* IsWild() - */ /* */ /*--------------------------------------------------------------------------*/ /* Returns TRUE iff the path contains * or ? */ BOOL APIENTRY IsWild( LPSTR lpszPath ) { while (*lpszPath) { if (*lpszPath == '?' || *lpszPath == '*') return (TRUE); lpszPath = AnsiNext(lpszPath); } return (FALSE); } /*--------------------------------------------------------------------------*/ /* */ /* CheckSlashies() - */ /* */ /*--------------------------------------------------------------------------*/ /* Replaces frontslashes (evil) with backslashes (good). */ VOID APIENTRY CheckSlashies( LPSTR lpT ) { while (*lpT) { if (*lpT == '/') *lpT = '\\'; lpT = AnsiNext(lpT); } } /*--------------------------------------------------------------------------*/ /* */ /* AddBackslash() - */ /* */ /*--------------------------------------------------------------------------*/ /* Ensures that a path ends with a backslash. */ VOID APIENTRY AddBackslash( LPSTR lpszPath ) { ENTER("AddBackslash"); PRINT(BF_PARMTRACE, "IN: lpszPath=%s", lpszPath); if (*AnsiPrev(lpszPath,lpszPath+lstrlen(lpszPath)) != '\\') lstrcat(lpszPath, "\\"); PRINT(BF_PARMTRACE, "OUT: lpszPath=%s", lpszPath); LEAVE("AddBackslash"); } /*--------------------------------------------------------------------------*/ /* */ /* StripBackslash() - */ /* */ /*--------------------------------------------------------------------------*/ /* Removes a trailing backslash from a proper directory name UNLESS it is * the root directory. Assumes a fully qualified directory path. */ VOID APIENTRY StripBackslash( LPSTR lpszPath ) { register WORD len; len = lstrlen(lpszPath) - (IsDBCSLeadByte(*AnsiPrev(lpszPath,lpszPath+lstrlen(lpszPath))) ? 2 : 1); if ((len == 2) || (lpszPath[len] != '\\')) return; lpszPath[len] = TEXT('\0'); } /*--------------------------------------------------------------------------*/ /* */ /* StripFilespec() - */ /* */ /*--------------------------------------------------------------------------*/ /* Remove the filespec portion from a path (including the backslash). */ VOID APIENTRY StripFilespec( LPSTR lpszPath ) { LPSTR p; p = lpszPath + lstrlen(lpszPath); while ((*p != '\\') && (*p != ':') && (p != lpszPath)) p = AnsiPrev(lpszPath, p); if (*p == ':') p++; /* Don't strip backslash from root directory entry. */ if (p != lpszPath) { if ((*p == '\\') && (*(p-1) == ':')) p++; } else p++; *p = TEXT('\0'); } /*--------------------------------------------------------------------------*/ /* */ /* StripPath() - */ /* */ /*--------------------------------------------------------------------------*/ /* Extract only the filespec portion from a path. */ VOID APIENTRY StripPath( LPSTR lpszPath ) { LPSTR p; ENTER("StripPath"); PRINT(BF_PARMTRACE, "IN: lpszPath=%s", lpszPath); p = lpszPath + lstrlen(lpszPath); while ((*p != '\\') && (*p != ':') && (p != lpszPath)) p = AnsiPrev(lpszPath, p); if (p != lpszPath || *p == '\\') p++; if (p != lpszPath) lstrcpy(lpszPath, p); PRINT(BF_PARMTRACE, "OUT: lpszPath=%s", lpszPath); LEAVE("StripPath"); } /*--------------------------------------------------------------------------*/ /* */ /* GetExtension() - */ /* */ /*--------------------------------------------------------------------------*/ /* Returns the extension part of a filename. */ LPSTR APIENTRY GetExtension( LPSTR pszFile ) { PSTR p, pSave = NULL; p = pszFile; while (*p) { if (*p == '.') pSave = p; p = (LPSTR)AnsiNext(p); } if (!pSave) return (p); return (LPSTR)AnsiNext(pSave); } /*--------------------------------------------------------------------------*/ /* */ /* FindExtensionInList() - */ /* */ /*--------------------------------------------------------------------------*/ /* Returns TRUE if 'lpszExt' is somewhere in 'pszList'. */ BOOL APIENTRY FindExtensionInList( LPSTR pszExt, LPSTR pszList ) { LPSTR p2; CHAR ch; while (*pszList) { /* Move to the next item in the list. */ while ((*pszList) && (*pszList == ' ')) pszList = (LPSTR)AnsiNext(pszList); if (!*pszList) break; /* NULL-terminate this item. */ p2 = (LPSTR)AnsiNext(pszList); while ((*p2) && (*p2 != ' ')) p2 = (LPSTR)AnsiNext(p2); ch = *p2; *p2 = TEXT('\0'); if (!lstrcmpi(pszExt, pszList)) { *p2 = ch; return (TRUE); } *p2 = ch; pszList = p2; } return (FALSE); } /*--------------------------------------------------------------------------*/ /* */ /* MyMessageBox() - */ /* */ /*--------------------------------------------------------------------------*/ INT APIENTRY MyMessageBox( HWND hWnd, WORD idTitle, WORD idMessage, WORD wStyle ) { CHAR szTemp[MAXMESSAGELEN]; HWND hwndT; LoadString(hAppInstance, idTitle, szTitle, sizeof(szTitle)); if (idMessage < 32) { LoadString(hAppInstance, IDS_UNKNOWNMSG, szTemp, sizeof(szTemp)); wsprintf(szMessage, szTemp, idMessage); } else LoadString(hAppInstance, idMessage, szMessage, sizeof(szMessage)); if (hWnd) hwndT = GetLastActivePopup(hWnd); else hwndT = hWnd; return MessageBox(hwndT, szMessage, szTitle, wStyle | MB_TASKMODAL); } /*--------------------------------------------------------------------------*/ /* */ /* ExecProgram() - */ /* */ /* all strings are OEM */ /*--------------------------------------------------------------------------*/ /* Returns 0 for success. Otherwise returns a IDS_ string code. */ WORD APIENTRY ExecProgram( LPSTR lpPath, LPSTR lpParms, LPSTR lpDir, BOOL bLoadIt ) { WORD ret; INT iCurCount; INT i; HCURSOR hCursor; ENTER("ExecProgram"); ret = 0; hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); iCurCount = ShowCursor(TRUE) - 1; /* open the object */ if (lpPath) OemToCharBuff(lpPath, lpPath, _MAX_PATH); if (lpParms) OemToCharBuff(lpParms, lpParms, _MAX_PATH); if (lpDir) OemToCharBuff(lpDir, lpDir, _MAX_PATH); // Shell Execute takes ansi string. // ret = (WORD)RealShellExecute(hwndFrame, NULL, lpPath, lpParms, lpDir, NULL, NULL, NULL, (WORD)(bLoadIt ? SW_SHOWMINNOACTIVE : SW_SHOWNORMAL), NULL); DosResetDTAAddress(); // undo any bad things COMMDLG did if (lpPath) AnsiToOem(lpPath, lpPath); if (lpParms) AnsiToOem(lpParms, lpParms); if (lpDir) AnsiToOem(lpDir, lpDir); switch (ret) { case 0: case 8: ret = IDS_NOMEMORYMSG; break; case 2: ret = IDS_FILENOTFOUNDMSG; break; case 3: case 5: // access denied ret = IDS_BADPATHMSG; break; case 4: ret = IDS_MANYOPENFILESMSG; break; case 10: ret = IDS_NEWWINDOWSMSG; break; case 12: ret = IDS_OS2APPMSG; break; case 15: /* KERNEL has already put up a messagebox for this one. */ ret = 0; break; case 16: ret = IDS_MULTIPLEDSMSG; break; case 18: ret = IDS_PMODEONLYMSG; break; case 19: ret = IDS_COMPRESSEDEXE; break; case 20: ret = IDS_INVALIDDLL; break; case SE_ERR_SHARE: ret = IDS_SHAREERROR; break; case SE_ERR_ASSOCINCOMPLETE: ret = IDS_ASSOCINCOMPLETE; break; case SE_ERR_DDETIMEOUT: case SE_ERR_DDEFAIL: case SE_ERR_DDEBUSY: ret = IDS_DDEFAIL; break; case SE_ERR_NOASSOC: ret = IDS_NOASSOCMSG; break; default: if (ret < 32) goto EPExit; if (bMinOnRun && !bLoadIt) ShowWindow(hwndFrame, SW_SHOWMINNOACTIVE); ret = 0; } EPExit: i = ShowCursor(FALSE); #if 0 /* Make sure that the cursor count is still balanced. */ if (i != iCurCount) ShowCursor(TRUE); #endif SetCursor(hCursor); PRINT(BF_PARMTRACE, "OUT: ret=%ud", ret); LEAVE("ExecProgram"); return ret; } /*--------------------------------------------------------------------------*/ /* */ /* IsProgramFile() - */ /* */ /*--------------------------------------------------------------------------*/ /* Returns TRUE is the Path points to a file which has one of the extentions * listed in the "Programs=" portions of WIN.INI. */ BOOL APIENTRY IsProgramFile( LPSTR lpszPath ) { LPSTR szExt; CHAR szTemp[MAXPATHLEN] = {0}; /* Move the string into our own DS. */ strncpy(szTemp, lpszPath, sizeof(szTemp)/sizeof(szTemp[0])-1); /* Get the file's extension. */ StripPath(szTemp); szExt = GetExtension(szTemp); if (!*szExt) { /* The specified path didn't have an extention. It can't be a program. */ return (FALSE); } return FindExtensionInList(szExt, szPrograms); } /*--------------------------------------------------------------------------*/ /* */ /* IsDocument() - */ /* */ /*--------------------------------------------------------------------------*/ /* Returns TRUE is the Path points to a file which has one of the extentions * listed in the "Documents=" portions of WIN.INI or one which has an Association. */ BOOL APIENTRY IsDocument( LPSTR lpszPath ) { LPSTR szExt; CHAR szTemp[MAXPATHLEN]; /* Move the string into our own DS. */ strncpy(szTemp, lpszPath, sizeof(szTemp)/sizeof(szTemp[0])-1); /* Get the file's extension. */ StripPath(szTemp); szExt = GetExtension(szTemp); if (!*szExt) { /* The specified path didn't have an extention. It can't be a program. */ return (FALSE); } return FindExtensionInList(szExt, szDocuments); }