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.
 
 
 
 
 
 

1362 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
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);
}