Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1379 lines
34 KiB

/****************************************************************************/
/* */
/* 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 NEAR PASCAL DriveType(INT iDrive)
{
if (rgiDriveType[iDrive] != -1)
return rgiDriveType[iDrive];
return rgiDriveType[iDrive] = MGetDriveType(iDrive);
}
VOID NEAR PASCAL 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);
OemToAnsi(pszDir,pszDir);
}
return;
} else
hwnd = (HWND)SendMessage(hwndMDIClient,WM_MDIGETACTIVE,0,0L);
hwndfound:
SendMessage(hwnd,FS_GETDIRECTORY,MAXPATHLEN,(LONG)(LPSTR)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)
{
#ifdef LFN
if (GetNameType(szPath) == FILE_83_CI)
#endif
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;
DWORD 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), (LONG)(LPSTR)szDir);
// update the drives windows
SendMessage(hwndActive, FS_CHANGEDRIVES, 0, 0L);
if (IsValidDisk(szDir[0] - 'A'))
lParam = (LONG)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;
#ifdef DBCS
for (p = szFile; *p; p = (LPSTR)AnsiNext(p))
#else
for (p = szFile; *p; p++)
#endif
{
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++ = '^';
#ifdef DBCS
if (IsDBCSLeadByte(*p++ = *pT++))
#endif
*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)GetWindowLong(hwnd, GWL_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);
}
}
// atoi with decimal comma seperators
//
//#ifdef INLIBRARY
LPSTR APIENTRY AddCommas(LPSTR szBuf, DWORD dw)
{
CHAR szTemp[40];
LPSTR pTemp;
INT count, len;
LPSTR p;
ENTER("AddCommas");
len = wsprintf(szTemp, "%ld", dw);
pTemp = szTemp + len - 1;
p = szBuf + len + ((len - 1) / 3);
*p-- = TEXT('\0'); // null terimnate the string we are building
count = 1;
while (pTemp >= szTemp) {
*p-- = *pTemp--;
if (count == 3) {
count = 1;
if (p > szBuf)
*p-- = szComma[0];
} else
count++;
}
LEAVE("AddCommas");
return szBuf;
}
//#endif
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;
#ifdef DBCS
for (lp = szTitle; *lp; lp = AnsiNext(lp))
#else
for (lp = szTitle; *lp; lp++)
#endif
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 FAR PASCAL GetBootDisk()
{
CHAR szTemp[MAXPATHLEN];
#if 0
if (wDOSversion >= 0x0400) {
_asm {
mov ax, 3305h ; get startup drive
int 21h
xor dh,dh ; clear high part
dec dl ; convert to zero based (A=0)
mov ax, dx
}
} else {
#endif
// well, close enough...
GetWindowsDirectory(szTemp, sizeof(szTemp));
return szTemp[0] - 'A';
#if 0
}
#endif
}
//
// 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(register INT iDrive)
{
return DriveType(iDrive) == DRIVE_REMOVABLE;
}
BOOL APIENTRY IsRemoteDrive(register 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)
{
#ifdef ORGCODE
DevPB dpbDiskParms; /* Device Parameters */
// try the fast way...
memset(&dpbDiskParms, 0, sizeof(dpbDiskParms));
if (!DeviceParameters(drive, &dpbDiskParms, IOCTL_GET_DPB))
return MAKELONG((WORD)dpbDiskParms.BPB.secPerClus, dpbDiskParms.BPB.cbSec);
// very slow way...
_asm {
mov ah,36h
mov dx,drive
inc dx ; make it 1 based.
int 21h
inc ax ; if Error, ax = -1, else, ax = sectors/cluster
jz GCSdone ; Yup, Error. Return zero.
dec ax ; Get back sectors/cluster.
mov dx, cx ; cx = bytes/sector
GCSdone:
}
#else
UNREFERENCED_PARAMETER(drive);
return 0;
#endif
}
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');
#ifdef OLD
if (!IsCDRomDrive(wDrive))
{
szDrive[0] = (CHAR)('A'+ wDrive);
szDrive[1] = ':';
szDrive[2] = 0;
if (WFGetConnection(szDrive,szVolShare,FALSE) != WN_SUCCESS) {
GetVolumeLabel(wDrive, szVolShare, TRUE);
OemToAnsi(szVolShare, szVolShare);
}
else
lstrcpy(szVolShare,"CD-ROM");
#else
lstrcpy(szVolShare, "Objects");
#endif
}
#ifdef LFN
/*--------------------------------------------------------------------------*/
/* */
/* 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, (LONG)&fDir);
if (p) {
LocalFree((HANDLE)p);
}
return(fDir);
}
#endif
/*--------------------------------------------------------------------------*/
/* */
/* 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 == ','))
#ifdef DBCS
pFrom = (LPSTR)AnsiNext(pFrom);
#else
pFrom++;
#endif
if (!*pFrom)
return(NULL);
if (*pFrom == '\"') {
#ifdef DBCS
pFrom = (LPSTR)AnsiNext(pFrom);
#else
pFrom++;
#endif
/* Find the next quote */
for (i=0; *pFrom && *pFrom != '\"';)
{
if (*pFrom == '^')
{
#ifdef DBCS
pFrom = (LPSTR)AnsiNext(pFrom)
#else
++pFrom;
#endif
if (!*pFrom)
break;
}
if (i < cbMax - 1)
{
#ifdef DBCS
i++;
if (IsDBCSLeadByte(*pTo++ = *pFrom++))
#endif
{
i++;
*pTo++ = *pFrom++;
}
}
}
#ifdef DBCS
pFrom = (LPSTR)AnsiNext(pFrom);
#else
pFrom++;
#endif
} else {
/* Find the next space or comma. */
for (i=0; *pFrom && *pFrom != ' ' && *pFrom != ',';) {
if (*pFrom == '^') {
#ifdef DBCS
pFrom = (LPSTR)AnsiNext(pFrom)
#else
++pFrom;
#endif
if (!*pFrom)
break;
}
if (i < cbMax - 1) {
#ifdef DBCS
i++;
if (IsDBCSLeadByte(*pTo++ = *pFrom++))
#endif
{
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 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);
hFont = (HANDLE)SendMessage(hDlgItem, WM_GETFONT, 0, 0L);
if (hFont = SelectObject(hDC, hFont)) {
MGetTextExtent(hDC, szMessage, lstrlen(szMessage), &dx, NULL);
CompactPath(hDC, szPath, (WORD)(rc.right-rc.left-dx));
}
SelectObject(hDC, 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);
#ifdef DBCS
lpszPath = AnsiNext(lpszPath);
#else
lpszPath++;
#endif
}
return(FALSE);
}
/*--------------------------------------------------------------------------*/
/* */
/* CheckSlashies() - */
/* */
/*--------------------------------------------------------------------------*/
/* Replaces frontslashes (evil) with backslashes (good). */
VOID APIENTRY CheckSlashies(LPSTR lpT)
{
while (*lpT)
{
if (*lpT == '/')
*lpT = '\\';
#ifdef DBCS
lpT = AnsiNext(lpT);
#else
lpT++;
#endif
}
}
/*--------------------------------------------------------------------------*/
/* */
/* 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;
#ifdef DBCS
len = lstrlen(lpszPath) - (IsDBCSLeadByte(*AnsiPrev(lpszPath,lpszPath+lstrlen(lpszPath))) ? 2 : 1);
#else
len = (WORD)(lstrlen(lpszPath) - 1);
#endif
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;
#ifdef DBCS
p = lpszPath + lstrlen(lpszPath);
while ((*p != '\\') && (*p != ':') && (p != lpszPath))
p = AnsiPrev(lpszPath, p);
#else
p = lpszPath + lstrlen(lpszPath);
while ((*p != '\\') && (*p != ':') && (p != lpszPath))
p--;
#endif
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);
#ifdef DBCS
while ((*p != '\\') && (*p != ':') && (p != lpszPath))
p = AnsiPrev(lpszPath, p);
#else
while ((*p != '\\') && (*p != ':') && (p != lpszPath))
p--;
#endif
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;
#ifdef DBCS
p = (LPSTR)AnsiNext(p);
#else
p++;
#endif
}
if (!pSave)
return(p);
#ifdef DBCS
return (LPSTR)AnsiNext(pSave);
#else
return pSave+1;
#endif
}
/*--------------------------------------------------------------------------*/
/* */
/* 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 == ' '))
#ifdef DBCS
pszList = (LPSTR)AnsiNext(pszList);
#else
pszList++;
#endif
if (!*pszList)
break;
/* NULL-terminate this item. */
#ifdef DBCS
p2 = (LPSTR)AnsiNext(pszList);
#else
p2 = pszList+1;
#endif
while ((*p2) && (*p2 != ' '))
#ifdef DBCS
p2 = (LPSTR)AnsiNext(p2);
#else
p2++;
#endif
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)
OemToAnsi(lpPath, lpPath);
if (lpParms)
OemToAnsi(lpParms, lpParms);
if (lpDir)
OemToAnsi(lpDir, lpDir);
// Shell Execute takes ansi string.
//
// BUGBUG: WIN31 and NT have different RealShellExecute params....
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];
/* Move the string into our own DS. */
lstrcpy(szTemp, lpszPath);
/* 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. */
lstrcpy(szTemp, lpszPath);
/* 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);
}