Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
fileopen.c
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 300k
Category:
Windows Kernel
Development Platform:
Visual C++
- cb += (int) SendDlgItemMessage(
- hDlg,
- lst2,
- LB_GETTEXT,
- (WPARAM)idir,
- (LPARAM)&pOFI->szPath[cb] );
- pOFI->szPath[cb++] = CHAR_BSLASH;
- }
- //
- // The root is a special case.
- //
- if (idirNew)
- {
- pOFI->szPath[cb - 1] = CHAR_NULL;
- }
- pstrPath = pOFI->szPath;
- }
- if (!*pstrPath ||
- (ChangeDir(hDlg, pstrPath, FALSE, TRUE) == CHANGEDIR_FAILED))
- {
- break;
- }
- //
- // List all directories under this one.
- //
- UpdateListBoxes(hDlg, pOFI, NULL, mskDirectory);
- if (pOFN->lpfnHook)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFN);
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- (*lpfnHook)( hDlg,
- msgLBCHANGEA,
- lst2,
- MAKELONG(LOWORD(idirNew), CD_LBSELCHANGE) );
- }
- else
- #endif
- {
- (*lpfnHook)( hDlg,
- msgLBCHANGEW,
- lst2,
- MAKELONG(LOWORD(idirNew), CD_LBSELCHANGE) );
- }
- }
- return (TRUE);
- }
- break;
- }
- case ( cmb2 ) :
- {
- switch (GET_WM_COMMAND_CMD(wParam, lParam))
- {
- case ( CBN_DROPDOWN ) :
- {
- pOFN->Flags |= OFN_DRIVEDOWN;
- return (TRUE);
- break;
- }
- case ( CBN_CLOSEUP ) :
- {
- //
- // It would seem reasonable to merely do the update
- // at this point, but that would rely on message
- // ordering, which isnt a smart move. In fact, if
- // you hit ALT-DOWNARROW, DOWNARROW, ALT-DOWNARROW,
- // you receive CBN_DROPDOWN, CBN_SELCHANGE, and then
- // CBN_CLOSEUP. But if you use the mouse to choose
- // the same element, the last two messages trade
- // places. PostMessage allows all messages in the
- // sequence to be processed, and then updates are
- // done as needed.
- //
- PostMessage( hDlg,
- WM_COMMAND,
- GET_WM_COMMAND_MPS(
- cmb2,
- GET_WM_COMMAND_HWND(wParam, lParam),
- MYCBN_DRAW ) );
- return (TRUE);
- break;
- }
- case ( MYCBN_LIST ) :
- {
- LoadDrives(hDlg);
- break;
- }
- case ( MYCBN_REPAINT ) :
- {
- int cchCurDir;
- LPTSTR lpCurDir;
- // sanity
- if (!(lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg)) ||
- !(lpCurDir = lpCurDlg->lpstrCurDir))
- {
- break;
- }
- cchCurDir = GetPathOffset(lpCurDir);
- if (cchCurDir != -1)
- {
- TCHAR szRepaintDir[CCHNETPATH];
- HWND hCmb2 = (HWND)lParam;
- lstrcpy(szRepaintDir, lpCurDir);
- szRepaintDir[cchCurDir] = CHAR_NULL;
- SendMessage( hCmb2,
- CB_SELECTSTRING,
- (WPARAM)-1,
- (LPARAM)szRepaintDir );
- }
- break;
- }
- case ( CBN_SELCHANGE ) :
- {
- StripFileName(hDlg, IS16BITWOWAPP(pOFN));
- //
- // Version check not needed, since flag never set
- // for versions not supporting CBN_CLOSEUP. Putting
- // check at CBN_DROPDOWN is more efficient since it
- // is less frequent than CBN_SELCHANGE.
- if (pOFN->Flags & OFN_DRIVEDOWN)
- {
- //
- // Don't fill lst2 while the combobox is down.
- //
- return (TRUE);
- break;
- }
- }
- case ( MYCBN_CHANGEDIR ) :
- case ( MYCBN_DRAW ) :
- {
- TCHAR szTitle[WARNINGMSGLENGTH];
- LPTSTR lpFilter;
- int nDiskInd, nInd;
- DWORD dwType;
- LPTSTR lpszPath = NULL;
- LPTSTR lpszDisk = NULL;
- HWND hCmb2;
- OFN_DISKINFO *pofndiDisk = NULL;
- static szDrawDir[CCHNETPATH];
- int nRet;
- HourGlass(TRUE);
- //
- // Clear Flag for future CBN_SELCHANGE messeges.
- //
- pOFN->Flags &= ~OFN_DRIVEDOWN;
- //
- // Change the drive.
- //
- szText[0] = CHAR_NULL;
- hCmb2 = (HWND)lParam;
- if (hCmb2 != NULL)
- {
- nInd = (int) SendMessage(hCmb2, CB_GETCURSEL, 0, 0L);
- if (nInd != CB_ERR)
- {
- SendMessage( hCmb2,
- CB_GETLBTEXT,
- nInd,
- (LPARAM)(LPTSTR)szDrawDir );
- }
- if ((nInd == CB_ERR) || ((INT_PTR)pofndiDisk == CB_ERR))
- {
- if (lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg))
- {
- if (lpCurDlg->lpstrCurDir)
- {
- lstrcpy((LPTSTR)szDrawDir,
- lpCurDlg->lpstrCurDir);
- }
- }
- }
- CharLower((LPTSTR)szDrawDir);
- //
- // Should always succeed.
- //
- nDiskInd = DiskAddedPreviously(0, (LPTSTR)szDrawDir);
- if (nDiskInd != 0xFFFFFFFF)
- {
- pofndiDisk = &gaDiskInfo[nDiskInd];
- }
- else
- {
- //
- // Skip update in the case where it fails.
- //
- return (TRUE);
- }
- dwType = pofndiDisk->dwType;
- lpszDisk = pofndiDisk->lpPath;
- }
- if ((GET_WM_COMMAND_CMD(wParam, lParam)) == MYCBN_CHANGEDIR)
- {
- if (lpNetDriveSync)
- {
- lpszPath = lpNetDriveSync;
- lpNetDriveSync = NULL;
- }
- else
- {
- if (lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg))
- {
- if (lpCurDlg->lpstrCurDir)
- {
- lstrcpy((LPTSTR)szDrawDir,
- lpCurDlg->lpstrCurDir);
- lpszPath = (LPTSTR)szDrawDir;
- }
- }
- }
- }
- else
- {
- lpszPath = lpszDisk;
- }
- if (bInitializing)
- {
- lpFilter = szTitle;
- if (pOFN->lpstrFile &&
- (StrChr(pOFN->lpstrFile, CHAR_STAR) ||
- StrChr(pOFN->lpstrFile, CHAR_QMARK)))
- {
- lstrcpy(lpFilter, pOFN->lpstrFile);
- }
- else
- {
- HWND hcmb1 = GetDlgItem(hDlg, cmb1);
- nInd = (int) SendMessage(hcmb1, CB_GETCURSEL, 0, 0L);
- if (nInd == CB_ERR)
- {
- //
- // No current selection.
- //
- goto NullSearch;
- }
- //
- // Must also check if filter contains anything.
- //
- if (nInd ||
- !(pOFN->lpstrCustomFilter &&
- *pOFN->lpstrCustomFilter))
- {
- lpFilter = (LPTSTR)(pOFN->lpstrFilter);
- lpFilter += SendMessage( hcmb1,
- CB_GETITEMDATA,
- (WPARAM)nInd,
- 0 );
- }
- else
- {
- lpFilter = pOFN->lpstrCustomFilter;
- lpFilter += lstrlen(pOFN->lpstrCustomFilter) + 1;
- }
- }
- }
- else
- {
- NullSearch:
- lpFilter = NULL;
- }
- //
- // UpdateListBoxes cuts up filter string in place.
- //
- if (lpFilter)
- {
- lstrcpy(szTitle, lpFilter);
- CharLower(szTitle);
- }
- if (dwType == REMDRVBMP)
- {
- DWORD err = WNetRestoreConnection(hDlg, lpszDisk);
- if (err != WN_SUCCESS)
- {
- HourGlass(FALSE);
- return (TRUE);
- }
- pofndiDisk->dwType = NETDRVBMP;
- SendMessage(
- hCmb2,
- CB_SETITEMDATA,
- (WPARAM)SendMessage(
- hCmb2,
- CB_SELECTSTRING,
- (WPARAM)-1,
- (LPARAM)(LPTSTR)pofndiDisk->lpAbbrName ),
- (LPARAM)NETDRVBMP );
- }
- //
- // Calls to ChangeDir will call SelDisk, so no need
- // to update cmb2 on our own here (used to be after
- // updatelistboxes).
- //
- if ((nRet = ChangeDir( hDlg,
- lpszPath,
- FALSE,
- FALSE )) == CHANGEDIR_FAILED)
- {
- int mbRet;
- while (nRet == CHANGEDIR_FAILED)
- {
- if (dwType == FLOPPYBMP)
- {
- mbRet = InvalidFileWarning(
- hDlg,
- lpszPath,
- ERROR_NO_DISK_IN_DRIVE,
- (UINT)(MB_RETRYCANCEL |
- MB_ICONEXCLAMATION));
- }
- else if (dwType == CDDRVBMP)
- {
- mbRet = InvalidFileWarning(
- hDlg,
- lpszPath,
- ERROR_NO_DISK_IN_CDROM,
- (UINT)(MB_RETRYCANCEL |
- MB_ICONEXCLAMATION) );
- }
- else
- {
- //
- // See if it's a RAW volume.
- //
- if (dwType == HARDDRVBMP &&
- GetLastError() == ERROR_UNRECOGNIZED_VOLUME)
- {
- mbRet = InvalidFileWarning(
- hDlg,
- lpszPath,
- ERROR_UNRECOGNIZED_VOLUME,
- (UINT)(MB_OK |
- MB_ICONEXCLAMATION) );
- }
- else
- {
- mbRet = InvalidFileWarning(
- hDlg,
- lpszPath,
- ERROR_DIR_ACCESS_DENIED,
- (UINT)(MB_RETRYCANCEL |
- MB_ICONEXCLAMATION) );
- }
- }
- if (bFirstTime || (mbRet != IDRETRY))
- {
- lpszPath = NULL;
- nRet = ChangeDir(hDlg, lpszPath, TRUE, FALSE);
- }
- else
- {
- nRet = ChangeDir(hDlg, lpszPath, FALSE, FALSE);
- }
- }
- }
- UpdateListBoxes( hDlg,
- pOFI,
- lpFilter ? szTitle : lpFilter,
- (WORD)(mskDrives | mskDirectory) );
- if (pOFN->lpfnHook)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFN);
- nInd = (int) SendDlgItemMessage( hDlg,
- cmb2,
- CB_GETCURSEL,
- 0,
- 0 );
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- (*lpfnHook)( hDlg,
- msgLBCHANGEA,
- cmb2,
- MAKELONG(LOWORD(nInd),
- CD_LBSELCHANGE) );
- }
- else
- #endif
- {
- (*lpfnHook)( hDlg,
- msgLBCHANGEW,
- cmb2,
- MAKELONG(LOWORD(nInd),
- CD_LBSELCHANGE) );
- }
- }
- HourGlass(FALSE);
- return (TRUE);
- break;
- }
- default :
- {
- break;
- }
- }
- break;
- }
- case ( pshHelp ) :
- {
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- if (msgHELPA && pOFN->hwndOwner)
- {
- SendMessage( pOFN->hwndOwner,
- msgHELPA,
- (WPARAM)hDlg,
- (DWORD_PTR)pOFN );
- }
- }
- else
- #endif
- {
- if (msgHELPW && pOFN->hwndOwner)
- {
- SendMessage( pOFN->hwndOwner,
- msgHELPW,
- (WPARAM)hDlg,
- (DWORD_PTR)pOFN );
- }
- }
- break;
- }
- case ( psh14 ) :
- {
- bGetNetDrivesSync = TRUE;
- if (CallNetDlg(hDlg))
- {
- LNDSetEvent(hDlg);
- }
- else
- {
- bGetNetDrivesSync = FALSE;
- }
- break;
- }
- default :
- {
- break;
- }
- }
- return (FALSE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // UpdateListBoxes
- //
- // Fills out File and Directory List Boxes in a single pass
- // given (potentially) multiple filters
- //
- // It assumes the string of extensions are delimited by semicolons.
- //
- // hDlg Handle to File Open/Save dialog
- // pOFI pointer to OPENFILEINFO structure
- // lpszFilter pointer to filter, if NULL, use pOFI->szSpecCur
- // wMask mskDirectory and/or mskDrives, or NULL
- //
- // Returns: TRUE if match
- // FALSE if not
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL UpdateListBoxes(
- HWND hDlg,
- POPENFILEINFO pOFI,
- LPTSTR lpszFilter,
- WORD wMask)
- {
- LPTSTR lpszF[MAXFILTERS + 1];
- LPTSTR lpszTemp;
- SHORT i, nFilters;
- HWND hFileList = GetDlgItem(hDlg, lst1);
- HWND hDirList = GetDlgItem(hDlg, lst2);
- BOOL bRet = FALSE;
- TCHAR szSpec[MAX_FULLPATHNAME];
- BOOL bDriveChange;
- BOOL bFindAll = FALSE;
- RECT rDirLBox;
- BOOL bLFN;
- HANDLE hff;
- DWORD dwErr;
- WIN32_FIND_DATA FindFileData;
- TCHAR szBuffer[MAX_FULLPATHNAME]; // add one for CHAR_DOT
- WORD wCount;
- LPCURDLG lpCurDlg;
- //
- // Save the drive bit and then clear it out.
- //
- bDriveChange = wMask & mskDrives;
- wMask &= ~mskDrives;
- if (!lpszFilter)
- {
- GetDlgItemText( hDlg,
- edt1,
- lpszFilter = szSpec,
- MAX_FULLPATHNAME - 1 );
- //
- // If any directory or drive characters are in there, or if there
- // are no wildcards, use the default spec.
- //
- if ( StrChr(szSpec, CHAR_BSLASH) ||
- StrChr(szSpec, CHAR_SLASH) ||
- StrChr(szSpec, CHAR_COLON) ||
- (!((StrChr(szSpec, CHAR_STAR)) ||
- (StrChr(szSpec, CHAR_QMARK)))) )
- {
- lstrcpy(szSpec, pOFI->szSpecCur);
- }
- else
- {
- lstrcpy(pOFI->szLastFilter, szSpec);
- }
- }
- //
- // We need to find out what kind of a drive we are running
- // on in order to determine if spaces are valid in a filename
- // or not.
- //
- bLFN = IsLFNDriveX(hDlg, TEXT(""));
- //
- // Find the first filter in the string, and add it to the
- // array.
- //
- if (bLFN)
- {
- lpszF[nFilters = 0] = lstrtok(lpszFilter, szSemiColonTab);
- }
- else
- {
- lpszF[nFilters = 0] = lstrtok(lpszFilter, szSemiColonSpaceTab);
- }
- //
- // Now we are going to loop through all the filters in the string
- // parsing the one we already have, and then finding the next one
- // and starting the loop over again.
- //
- while (lpszF[nFilters] && (nFilters < MAXFILTERS))
- {
- //
- // Check to see if the first character is a space.
- // If so, remove the spaces, and save the pointer
- // back into the same spot. Why? because the
- // FindFirstFile/Next api will _still_ work on
- // filenames that begin with a space because
- // they also look at the short names. The
- // short names will begin with the same first
- // real letter as the long filename. For
- // example, the long filename is " my document"
- // the first letter of this short name is "m",
- // so searching on "m*.*" or " m*.*" will yield
- // the same results.
- //
- if (bLFN && (*lpszF[nFilters] == CHAR_SPACE))
- {
- lpszTemp = lpszF[nFilters];
- while ((*lpszTemp == CHAR_SPACE) && *lpszTemp)
- {
- lpszTemp = CharNext(lpszTemp);
- }
- lpszF[nFilters] = lpszTemp;
- }
- //
- // The original code used to do a CharUpper here to put the
- // filter strings in upper case. EG: *.TXT However, this
- // is not a good thing to do for Turkish. Capital 'i' does
- // not equal 'I', so the CharUpper is being removed.
- //
- // CharUpper(lpszF[nFilters]);
- //
- // Compare the filter with *.*. If we find *.* then
- // set the boolean bFindAll, and this will cause the
- // files listbox to be filled in at the same time the
- // directories listbox is filled. This saves time
- // from walking the directory twice (once for the directory
- // names and once for the filenames).
- //
- if (!lstrcmpi(lpszF[nFilters], szStarDotStar))
- {
- bFindAll = TRUE;
- }
- //
- // Now we need to check if this filter is a duplicate
- // of an already existing filter.
- //
- for (wCount = 0; wCount < nFilters; wCount++)
- {
- //
- // If we find a duplicate, decrement the current
- // index pointer by one so that the last location
- // is written over (thus removing the duplicate),
- // and break out of this loop.
- //
- if (!lstrcmpi(lpszF[nFilters], lpszF[wCount]))
- {
- nFilters--;
- break;
- }
- }
- //
- // Ready to move on to the next filter. Find the next
- // filter based upon the type of file system we're using.
- //
- if (bLFN)
- {
- lpszF[++nFilters] = lstrtok(NULL, szSemiColonTab);
- }
- else
- {
- lpszF[++nFilters] = lstrtok(NULL, szSemiColonSpaceTab);
- }
- //
- // In case we found a pointer to NULL, then look for the
- // next filter.
- //
- while (lpszF[nFilters] && !*lpszF[nFilters])
- {
- if (bLFN)
- {
- lpszF[nFilters] = lstrtok(NULL, szSemiColonTab);
- }
- else
- {
- lpszF[nFilters] = lstrtok(NULL, szSemiColonSpaceTab);
- }
- }
- }
- //
- // Add NULL terminator only if needed.
- //
- if (nFilters >= MAXFILTERS)
- {
- lpszF[MAXFILTERS] = 0;
- }
- HourGlass(TRUE);
- SendMessage(hFileList, WM_SETREDRAW, FALSE, 0L);
- SendMessage(hFileList, LB_RESETCONTENT, 0, 0L);
- if (wMask & mskDirectory)
- {
- wNoRedraw |= 2; // HACK!!! WM_SETREDRAW isn't complete
- SendMessage(hDirList, WM_SETREDRAW, FALSE, 0L);
- //
- // LB_RESETCONTENT causes InvalidateRect(hDirList, 0, TRUE) to be
- // sent as well as repositioning the scrollbar thumb and drawing
- // it immediately. This causes flicker when the LB_SETCURSEL is
- // made, as it clears out the listbox by erasing the background of
- // each item.
- //
- SendMessage(hDirList, LB_RESETCONTENT, 0, 0L);
- }
- //
- // Always open enumeration for *.*
- //
- lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg);
- SetCurrentDirectory(lpCurDlg ? lpCurDlg->lpstrCurDir : NULL);
- hff = FindFirstFile(szStarDotStar, &FindFileData);
- if ( hff == INVALID_HANDLE_VALUE)
- {
- //
- // Error. Call GetLastError to determine what happened.
- //
- dwErr = GetLastError();
- //
- // With the ChangeDir logic handling AccessDenied for cds,
- // if we are not allowed to enum files, that's ok, just get out.
- //
- if (dwErr == ERROR_ACCESS_DENIED)
- {
- wMask = mskDirectory;
- goto Func4EFailure;
- }
- //
- // For bad path of bad filename.
- //
- if (dwErr != ERROR_FILE_NOT_FOUND)
- {
- wMask = mskDrives;
- goto Func4EFailure;
- }
- }
- //
- // A listing was made, even if empty.
- //
- bRet = TRUE;
- wMask &= mskDirectory;
- //
- // GetLastError says no more files.
- //
- if (hff == INVALID_HANDLE_VALUE && dwErr == ERROR_FILE_NOT_FOUND)
- {
- //
- // Things went well, but there are no files.
- //
- goto NoMoreFilesFound;
- }
- do
- {
- if (pOFI->pOFN->Flags & OFN_NOLONGNAMES)
- {
- #ifdef UNICODE
- UNICODE_STRING Name;
- BOOLEAN fSpace = FALSE;
- RtlInitUnicodeString(&Name, FindFileData.cFileName);
- if (RtlIsNameLegalDOS8Dot3(&Name, NULL, &fSpace) && !fSpace)
- {
- //
- // Legal 8.3 name and no spaces, so use the principal
- // file name.
- //
- lstrcpy(szBuffer, (LPTSTR)FindFileData.cFileName);
- }
- else
- #endif
- {
- #ifdef WINNT
- if (FindFileData.cAlternateFileName[0] == CHAR_NULL)
- {
- continue;
- }
- //
- // Use the alternate file name.
- //
- lstrcpy(szBuffer, (LPTSTR)FindFileData.cAlternateFileName);
- #else
- if (FindFileData.cAlternateFileName[0])
- {
- //
- // Use the alternate file name.
- //
- lstrcpy(szBuffer, (LPTSTR)FindFileData.cAlternateFileName);
- }
- else
- {
- //
- // Use the main file name.
- //
- lstrcpy(szBuffer, (LPTSTR)FindFileData.cFileName);
- }
- #endif
- }
- }
- else
- {
- lstrcpy(szBuffer, (LPTSTR)FindFileData.cFileName);
- }
- if ((FindFileData.dwFileAttributes & EXCLBITS))
- {
- continue;
- }
- if ((pOFI->pOFN->Flags & OFN_ALLOWMULTISELECT))
- {
- if (StrChr(szBuffer, CHAR_SPACE))
- {
- //
- // HPFS does not support alternate filenames
- // for multiselect, bump all spacey filenames.
- //
- if (FindFileData.cAlternateFileName[0] == CHAR_NULL)
- {
- continue;
- }
- lstrcpy(szBuffer, (LPTSTR)FindFileData.cAlternateFileName);
- }
- }
- if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- if (wMask & mskDirectory)
- {
- //
- // Don't include the subdirectories "." and "..".
- //
- if (szBuffer[0] == CHAR_DOT)
- {
- if ((szBuffer[1] == CHAR_NULL) ||
- ((szBuffer[1] == CHAR_DOT) && (szBuffer[2] == CHAR_NULL)))
- {
- continue;
- }
- }
- if (!bCasePreserved)
- {
- CharLower(szBuffer);
- }
- i = (WORD)SendMessage( hDirList,
- LB_ADDSTRING,
- 0,
- (DWORD_PTR)szBuffer );
- }
- }
- else if (bFindAll)
- {
- if (!bCasePreserved)
- {
- CharLower(szBuffer);
- }
- SendMessage(hFileList, LB_ADDSTRING, 0, (DWORD_PTR)szBuffer);
- }
- } while (FindNextFile(hff, &FindFileData));
- if (hff == INVALID_HANDLE_VALUE)
- {
- goto Func4EFailure;
- }
- FindClose(hff);
- if (!bFindAll)
- {
- for (i = 0; lpszF[i]; i++)
- {
- if (!lstrcmpi(lpszF[i], szStarDotStar))
- {
- continue;
- }
- //
- // Find First for each filter.
- //
- hff = FindFirstFile(lpszF[i], &FindFileData);
- if (hff == INVALID_HANDLE_VALUE)
- {
- DWORD dwErr = GetLastError();
- if ((dwErr == ERROR_FILE_NOT_FOUND) ||
- (dwErr == ERROR_INVALID_NAME))
- {
- //
- // Things went well, but there are no files.
- //
- continue;
- }
- else
- {
- wMask = mskDrives;
- goto Func4EFailure;
- }
- }
- do
- {
- if (pOFI->pOFN->Flags & OFN_NOLONGNAMES)
- {
- #ifdef UNICODE
- UNICODE_STRING Name;
- BOOLEAN fSpace = FALSE;
- RtlInitUnicodeString(&Name, FindFileData.cFileName);
- if (RtlIsNameLegalDOS8Dot3(&Name, NULL, &fSpace) && !fSpace)
- {
- //
- // Legal 8.3 name and no spaces, so use the principal
- // file name.
- //
- lstrcpy(szBuffer, (LPTSTR)FindFileData.cFileName);
- }
- else
- #endif
- {
- #ifdef WINNT
- if (FindFileData.cAlternateFileName[0] == CHAR_NULL)
- {
- continue;
- }
- //
- // Use the alternate file name.
- //
- lstrcpy( szBuffer,
- (LPTSTR)FindFileData.cAlternateFileName );
- #else
- if (FindFileData.cAlternateFileName[0])
- {
- //
- // Use the alternate file name.
- //
- lstrcpy( szBuffer,
- (LPTSTR)FindFileData.cAlternateFileName );
- }
- else
- {
- //
- // Use the main file name.
- //
- lstrcpy(szBuffer, (LPTSTR)FindFileData.cFileName);
- }
- #endif
- }
- }
- else
- {
- lstrcpy(szBuffer, (LPTSTR)FindFileData.cFileName);
- if (pOFI->pOFN->Flags & OFN_ALLOWMULTISELECT)
- {
- if (StrChr(szBuffer, CHAR_SPACE))
- {
- //
- // HPFS does not support alternate filenames
- // for multiselect, bump all spacey filenames.
- //
- if (FindFileData.cAlternateFileName[0] == CHAR_NULL)
- {
- continue;
- }
- lstrcpy( szBuffer,
- (LPTSTR)FindFileData.cAlternateFileName );
- }
- }
- }
- if ((FindFileData.dwFileAttributes & EXCLBITS) ||
- (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- continue;
- }
- if (!bCasePreserved)
- {
- CharLower(szBuffer);
- }
- SendMessage(hFileList, LB_ADDSTRING, 0, (DWORD_PTR)szBuffer);
- } while (FindNextFile(hff, &FindFileData));
- if (hff != INVALID_HANDLE_VALUE)
- {
- FindClose(hff);
- }
- }
- }
- NoMoreFilesFound:
- Func4EFailure:
- if (wMask)
- {
- if (wMask == mskDirectory)
- {
- LPTSTR lpCurDir = NULL;
- if (lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg))
- {
- lpCurDir = lpCurDlg->lpstrCurDir;
- }
- FillOutPath(hDirList, pOFI);
- //
- // The win31 way of chopping the text by just passing
- // it on to user doesn't work for unc names since user
- // doesn't see the drivelessness of them (thinks drive is
- // a bslash char). So, special case it here.
- //
- lstrcpy(pOFI->szPath, lpCurDir);
- if (DBL_BSLASH(pOFI->szPath))
- {
- SetDlgItemText(hDlg, stc1, ChopText(hDlg, stc1, pOFI->szPath));
- }
- else
- {
- DlgDirList(hDlg, pOFI->szPath, 0, stc1, DDL_READONLY);
- }
- SendMessage(hDirList, LB_SETCURSEL, pOFI->idirSub - 1, 0L);
- if (bDriveChange)
- {
- //
- // The design here is to show the selected drive whenever the
- // user changes drives, or whenever the number of
- // subdirectories is sufficiently low to allow them to be
- // shown along with the drive. Otherwise, show the
- // immediate parent and all the children that can be shown.
- // This all was done to meet the UITF spec.
- //
- i = 0;
- }
- else
- {
- //
- // Show as many children as possible.
- //
- if ((i = (SHORT)(pOFI->idirSub - 2)) < 0)
- {
- i = 0;
- }
- }
- //
- // LB_SETTOPINDEX must be after LB_SETCURSEL, as LB_SETCURSEL will
- // alter the top index to bring the current selection into view.
- //
- SendMessage(hDirList, LB_SETTOPINDEX, (WPARAM)i, 0L);
- }
- else
- {
- SetDlgItemText(hDlg, stc1, szNull);
- }
- wNoRedraw &= ~2;
- SendMessage(hDirList, WM_SETREDRAW, TRUE, 0L);
- GetWindowRect(hDirList, (LPRECT)&rDirLBox);
- rDirLBox.left++, rDirLBox.top++;
- rDirLBox.right--, rDirLBox.bottom--;
- MapWindowPoints(NULL, hDlg, (LPPOINT)&rDirLBox, 2);
- //
- // If there are less than enough directories to fill the listbox,
- // Win 3.0 doesn't clear out the bottom. Pass TRUE as the last
- // parameter to demand a WM_ERASEBACKGROUND message.
- //
- InvalidateRect(hDlg, (LPRECT)&rDirLBox, (BOOL)(wWinVer < 0x030A));
- }
- SendMessage(hFileList, WM_SETREDRAW, TRUE, 0L);
- InvalidateRect(hFileList, (LPRECT)0, (BOOL)TRUE);
- #ifndef WIN32
- ResetDTAAddress();
- #endif
- HourGlass(FALSE);
- return (bRet);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // OKButtonPressed
- //
- // Note: There are 4 cases for validation of a file name:
- // 1) OFN_NOVALIDATE allows invalid characters
- // 2) No validation flags No invalid characters, but path need not exist
- // 3) OFN_PATHMUSTEXIST No invalid characters, path must exist
- // 4) OFN_FILEMUSTEXIST No invalid characters, path & file must exist
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL OKButtonPressed(
- HWND hDlg,
- POPENFILEINFO pOFI,
- BOOL bSave)
- {
- DWORD nErrCode = 0;
- DWORD cch;
- DWORD cchSearchPath;
- LPOPENFILENAME pOFN = pOFI->pOFN;
- int nFileOffset, nExtOffset;
- HANDLE hFile;
- BOOL bAddExt = FALSE;
- BOOL bUNCName = FALSE;
- int nTempOffset;
- TCHAR szPathName[MAX_FULLPATHNAME];
- DWORD lRet;
- BOOL blfn;
- LPCURDLG lpCurDlg;
- TCHAR ch = 0;
- if (cch = GetUNCDirectoryFromLB(hDlg, lst2, pOFI))
- {
- nTempOffset = (WORD)(DWORD)SendDlgItemMessage( hDlg,
- lst2,
- LB_GETTEXTLEN,
- 0,
- 0 );
- }
- else
- {
- nTempOffset = 0;
- }
- GetDlgItemText(hDlg, edt1, pOFI->szPath + cch, MAX_FULLPATHNAME - 1);
- if (cch)
- {
- //
- // If a drive or new UNC was specified, forget the old UNC.
- //
- if ((pOFI->szPath[cch + 1] == CHAR_COLON) ||
- (DBL_BSLASH(pOFI->szPath + cch)) )
- {
- lstrcpy(pOFI->szPath, pOFI->szPath + cch);
- }
- else if ((ISBACKSLASH(pOFI->szPath, cch)) ||
- (pOFI->szPath[cch] == CHAR_SLASH))
- {
- //
- // If a directory from the root is given, put it immediately
- // after the \servershare listing.
- //
- lstrcpy(pOFI->szPath + nTempOffset, pOFI->szPath + cch);
- }
- }
- if (pOFN->Flags & OFN_NOLONGNAMES)
- {
- blfn = FALSE;
- }
- else
- {
- blfn = IsLFNDriveX(hDlg, pOFI->szPath);
- }
- lRet = ParseFile(pOFI->szPath, blfn, IS16BITWOWAPP(pOFN), FALSE);
- nFileOffset = (int)(SHORT)LOWORD(lRet);
- nExtOffset = (int)(SHORT)HIWORD(lRet);
- if (nFileOffset == PARSE_EMPTYSTRING)
- {
- UpdateListBoxes(hDlg, pOFI, NULL, 0);
- return (FALSE);
- }
- else if ((nFileOffset != PARSE_DIRECTORYNAME) &&
- (pOFN->Flags & OFN_NOVALIDATE))
- {
- pOFN->nFileOffset = (WORD)nFileOffset;
- pOFN->nFileExtension = (WORD)nExtOffset;
- if (pOFN->lpstrFile)
- {
- cch = lstrlen(pOFI->szPath);
- if (cch < pOFN->nMaxFile)
- {
- lstrcpy(pOFN->lpstrFile, pOFI->szPath);
- }
- else
- {
- //
- // For single file requests, we will never go over 64K
- // because the filesystem is limited to 256.
- //
- if (cch > 0x0000FFFF)
- {
- pOFN->lpstrFile[0] = (TCHAR)0xFFFF;
- }
- else
- {
- pOFN->lpstrFile[0] = (TCHAR)LOWORD(cch);
- }
- pOFN->lpstrFile[1] = CHAR_NULL;
- }
- }
- return (TRUE);
- }
- else if ((pOFN->Flags & OFN_ALLOWMULTISELECT) &&
- SpacesExist(pOFI->szPath))
- {
- return (MultiSelectOKButton(hDlg, pOFI, bSave));
- }
- else if (pOFI->szPath[nExtOffset] == CHAR_SEMICOLON)
- {
- pOFI->szPath[nExtOffset] = CHAR_NULL;
- nFileOffset = (int)(SHORT)LOWORD(ParseFile( pOFI->szPath,
- blfn,
- IS16BITWOWAPP(pOFN),
- FALSE ));
- pOFI->szPath[nExtOffset] = CHAR_SEMICOLON;
- if ( (nFileOffset >= 0) &&
- (StrChr(pOFI->szPath + nFileOffset, CHAR_STAR) ||
- StrChr(pOFI->szPath + nFileOffset, CHAR_QMARK)) )
- {
- lstrcpy(pOFI->szLastFilter, pOFI->szPath + nFileOffset);
- if (FListAll(pOFI, hDlg, pOFI->szPath) == CHANGEDIR_FAILED)
- {
- //
- // Conform with cchSearchPath error code settings in
- // PathCheck.
- //
- cchSearchPath = 2;
- goto PathCheck;
- }
- return (FALSE);
- }
- else
- {
- nFileOffset = PARSE_INVALIDCHAR;
- goto Warning;
- }
- }
- else if (nFileOffset == PARSE_DIRECTORYNAME)
- {
- //
- // End with slash?
- //
- if ((ISBACKSLASH(pOFI->szPath, nExtOffset - 1)) ||
- (pOFI->szPath[nExtOffset - 1] == CHAR_SLASH))
- {
- //
- // ... and is not the root, get rid of the slash.
- //
- if ( (nExtOffset != 1) &&
- (pOFI->szPath[nExtOffset - 2] != CHAR_COLON) &&
- (nExtOffset != nTempOffset + 1) )
- {
- pOFI->szPath[nExtOffset - 1] = CHAR_NULL;
- }
- }
- else if ((pOFI->szPath[nExtOffset - 1] == CHAR_DOT) &&
- ((pOFI->szPath[nExtOffset - 2] == CHAR_DOT) ||
- (ISBACKSLASH(pOFI->szPath, nExtOffset - 2)) ||
- (pOFI->szPath[nExtOffset - 2] == CHAR_SLASH)) &&
- ((DBL_BSLASH(pOFI->szPath)) ||
- ((*(pOFI->szPath + 1) == CHAR_COLON) &&
- (DBL_BSLASH(pOFI->szPath + 2)))))
- {
- pOFI->szPath[nExtOffset] = CHAR_BSLASH;
- pOFI->szPath[nExtOffset + 1] = CHAR_NULL;
- }
- //
- // Fall through to Directory Checking.
- //
- }
- else if (nFileOffset < 0)
- {
- //
- // Put in nErrCode so that call can be used from other points.
- //
- nErrCode = (DWORD)nFileOffset;
- Warning:
- //
- // If the disk is not a floppy and they tell me there's no
- // disk in the drive, dont believe it. Instead, put up the error
- // message that they should have given us.
- // (Note that the error message is checked first since checking
- // the drive type is slower.)
- //
- if (nErrCode == ERROR_ACCESS_DENIED)
- {
- if (bUNCName)
- {
- nErrCode = ERROR_NETWORK_ACCESS_DENIED;
- }
- else
- {
- szPathName[0] = (TCHAR)CharLower((LPTSTR)(DWORD)szPathName[0]);
- if (GetDiskType(szPathName) == DRIVE_REMOTE)
- {
- nErrCode = ERROR_NETWORK_ACCESS_DENIED;
- }
- else if (GetDiskType(szPathName) == DRIVE_REMOVABLE)
- {
- nErrCode = ERROR_NO_DISK_IN_DRIVE;
- }
- else if (GetDiskType(szPathName) == DRIVE_CDROM)
- {
- nErrCode = ERROR_NO_DISK_IN_CDROM;
- }
- }
- }
- if ((nErrCode == ERROR_WRITE_PROTECT) ||
- (nErrCode == ERROR_CANNOT_MAKE) ||
- (nErrCode == ERROR_NO_DISK_IN_DRIVE) ||
- (nErrCode == ERROR_NO_DISK_IN_CDROM))
- {
- pOFI->szPath[0] = szPathName[0];
- }
- InvalidFileWarning(hDlg, pOFI->szPath, nErrCode, 0);
- //
- // Can't cd case (don't want WM_ACTIVATE to setevent to GetNetDrives!).
- // Reset wNoRedraw.
- //
- wNoRedraw &= ~1;
- return (FALSE);
- }
- bUNCName = ((DBL_BSLASH(pOFI->szPath)) ||
- ((*(pOFI->szPath + 1) == CHAR_COLON) &&
- (DBL_BSLASH(pOFI->szPath + 2))));
- nTempOffset = nFileOffset;
- //
- // Get the fully-qualified path.
- //
- {
- BOOL bSlash;
- BOOL bRet;
- WORD nNullOffset;
- if (nFileOffset != PARSE_DIRECTORYNAME)
- {
- ch = *(pOFI->szPath + nFileOffset);
- *(pOFI->szPath + nFileOffset) = CHAR_NULL;
- nNullOffset = (WORD) nFileOffset;
- }
- //
- // For files of the format c:filename where c is not the
- // current directory, SearchPath does not return the curdir of c
- // so, prefetch it - should searchpath be changed?
- //
- if (nFileOffset)
- {
- if (*(pOFI->szPath + nFileOffset - 1) == CHAR_COLON)
- {
- //
- // If it fails, fall through to the error generated below.
- //
- if (ChangeDir(hDlg, pOFI->szPath, FALSE, FALSE) != CHANGEDIR_FAILED)
- {
- //
- // Replace old null offset.
- //
- *(pOFI->szPath + nFileOffset) = ch;
- ch = *pOFI->szPath;
- //
- // Don't pass drive-colon into search path.
- //
- *pOFI->szPath = CHAR_NULL;
- nNullOffset = 0;
- }
- }
- }
- if (bSlash = (*pOFI->szPath == CHAR_SLASH))
- {
- *pOFI->szPath = CHAR_BSLASH;
- }
- szPathName[0] = CHAR_NULL;
- HourGlass(TRUE);
- //
- // BUGBUG:
- // Each wow thread can change the current directory.
- // Since searchpath doesn't check current dirs on a per thread basis,
- // reset it here and hope that we don't get interrupted between
- // setting and searching...
- //
- lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg);
- SetCurrentDirectory(lpCurDlg ? lpCurDlg->lpstrCurDir : NULL);
- if (pOFI->szPath[0] == TEXT('')) // space for name (pretend it's valid for now)
- {
- lstrcpy(szPathName, (lpCurDlg ? lpCurDlg->lpstrCurDir : NULL));
- bRet = 1;
- }
- else
- {
- bRet = GetFullPathName( pOFI->szPath,
- MAX_FULLPATHNAME,
- szPathName,
- NULL );
- }
- if (!bRet && (pOFI->szPath[1] == CHAR_COLON))
- {
- int nDriveIndex = DiskAddedPreviously(pOFI->szPath[0], NULL);
- //
- // If it's a remembered connection, try to reconnect it.
- //
- if (nDriveIndex != 0xFFFFFFFF &&
- gaDiskInfo[nDriveIndex].dwType == REMDRVBMP)
- {
- DWORD err = WNetRestoreConnection( hDlg,
- gaDiskInfo[nDriveIndex].lpPath );
- if (err == WN_SUCCESS)
- {
- gaDiskInfo[nDriveIndex].dwType = NETDRVBMP;
- nDriveIndex = (int) SendDlgItemMessage(
- hDlg,
- cmb2,
- CB_SELECTSTRING,
- (WPARAM)-1,
- (LPARAM)(LPTSTR)gaDiskInfo[nDriveIndex].lpPath );
- SendDlgItemMessage( hDlg,
- cmb2,
- CB_SETITEMDATA,
- (WPARAM)nDriveIndex,
- (LPARAM)NETDRVBMP );
- bRet = GetFullPathName( pOFI->szPath,
- MAX_FULLPATHNAME,
- szPathName,
- NULL);
- }
- }
- }
- HourGlass(FALSE);
- if (nFileOffset != PARSE_DIRECTORYNAME)
- {
- *(pOFI->szPath + nNullOffset) = ch;
- }
- if (bSlash)
- {
- *pOFI->szPath = CHAR_SLASH;
- }
- if (bRet)
- {
- cchSearchPath = 0;
- if (nFileOffset != PARSE_DIRECTORYNAME)
- {
- ch = *(szPathName + lstrlen(szPathName) - 1);
- if (!ISBACKSLASH(szPathName, lstrlen(szPathName) - 1))
- {
- lstrcat(szPathName, TEXT("\"));
- }
- lstrcat(szPathName, (LPTSTR)(pOFI->szPath + nFileOffset));
- }
- else
- {
- //
- // Hack to get around SearchPath inconsistencies.
- //
- // searching for c: returns c:
- // searching for server share dir1 .. returns server share
- // in these two cases bypass the regular ChangeDir call that
- // uses szPathName and use the original pOFI->szPath instead
- // OKButtonPressed needs to be simplified!
- //
- int cch = GetPathOffset(pOFI->szPath);
- if (cch > 0)
- {
- if (bUNCName)
- {
- //
- // If this fails, how is szPathName used?
- // szPathName's disk should equal pOFI->szPath's
- // so the cch will be valid.
- //
- szPathName[cch] = CHAR_BSLASH;
- szPathName[cch + 1] = CHAR_NULL;
- if (ChangeDir( hDlg,
- pOFI->szPath,
- FALSE,
- TRUE ) != CHANGEDIR_FAILED)
- {
- goto ChangedDir;
- }
- }
- else
- {
- if (!pOFI->szPath[cch])
- {
- if (ChangeDir( hDlg,
- pOFI->szPath,
- FALSE,
- TRUE) != CHANGEDIR_FAILED)
- {
- goto ChangedDir;
- }
- }
- }
- }
- }
- }
- else
- {
- if (!(pOFN->Flags & OFN_PATHMUSTEXIST))
- {
- lstrcpy(szPathName, pOFI->szPath);
- }
- if (((nErrCode = GetLastError()) == ERROR_INVALID_DRIVE) ||
- (pOFI->szPath[1] == CHAR_COLON))
- {
- cchSearchPath = 1;
- }
- else
- {
- cchSearchPath = 2;
- }
- }
- }
- //
- // Full pattern?
- //
- if ( !cchSearchPath &&
- ((StrChr(pOFI->szPath + nFileOffset, CHAR_STAR)) ||
- (StrChr(pOFI->szPath + nFileOffset, CHAR_QMARK))) )
- {
- TCHAR szSameDirFile[MAX_FULLPATHNAME];
- if (nTempOffset)
- {
- //
- // Must restore character in case it is part of the filename,
- // e.g. nTempOffset is 1 for "foo.txt".
- //
- ch = pOFI->szPath[nTempOffset];
- pOFI->szPath[nTempOffset] = 0;
- ChangeDir(hDlg, pOFI->szPath, FALSE, TRUE);
- pOFI->szPath[nTempOffset] = ch;
- }
- if (!nExtOffset)
- {
- lstrcat(pOFI->szPath + nFileOffset, TEXT("."));
- }
- lstrcpy(szSameDirFile, pOFI->szPath + nFileOffset);
- lstrcpy(pOFI->szLastFilter, pOFI->szPath + nFileOffset);
- if (FListAll(pOFI, hDlg, szSameDirFile) < 0)
- {
- MessageBeep(0);
- }
- return (FALSE);
- }
- //
- // We either have a file pattern or a real file.
- // If its a directory
- // (1) Add on default pattern
- // (2) Act like its a pattern (goto pattern (1))
- // Else if its a pattern
- // (1) Update everything
- // (2) display files in whatever dir were now in
- // Else if its a file name!
- // (1) Check out the syntax
- // (2) End the dialog given OK
- // (3) Beep/message otherwise
- //
- //
- // Drive-letter:dirpath ??
- //
- if (!cchSearchPath)
- {
- DWORD dwFileAttr;
- if ((dwFileAttr = GetFileAttributes(szPathName)) != 0xFFFFFFFF)
- {
- if (dwFileAttr & FILE_ATTRIBUTE_DIRECTORY)
- {
- if (ChangeDir(hDlg, szPathName, FALSE, TRUE) != CHANGEDIR_FAILED)
- {
- ChangedDir:
- SendDlgItemMessage(hDlg, edt1, WM_SETREDRAW, FALSE, 0L);
- if (*pOFI->szLastFilter)
- {
- SetDlgItemText(hDlg, edt1, pOFI->szLastFilter);
- }
- else
- {
- SetDlgItemText(hDlg, edt1, szStarDotStar);
- }
- SendMessage( hDlg,
- WM_COMMAND,
- GET_WM_COMMAND_MPS( cmb1,
- GetDlgItem(hDlg, cmb1),
- CBN_CLOSEUP ) );
- SendMessage( hDlg,
- WM_COMMAND,
- GET_WM_COMMAND_MPS( cmb2,
- GetDlgItem(hDlg, cmb2),
- MYCBN_CHANGEDIR ) );
- SendDlgItemMessage(hDlg, edt1, WM_SETREDRAW, TRUE, 0L);
- InvalidateRect(GetDlgItem(hDlg, edt1), NULL, FALSE);
- }
- return (FALSE);
- }
- }
- }
- //
- // Was there a path and did it fail?
- //
- if (nFileOffset && cchSearchPath && (pOFN->Flags & OFN_PATHMUSTEXIST))
- {
- PathCheck:
- if (cchSearchPath == 2)
- {
- nErrCode = ERROR_PATH_NOT_FOUND;
- }
- else if (cchSearchPath == 1)
- {
- int nDriveIndex;
- //
- // Lowercase drive letters since DiskAddedPreviously is case
- // sensitive.
- //
- CharLower(pOFI->szPath);
- // We can get here without performing an OpenFile call. As such
- // the szPathName can be filled with random garbage. Since we
- // only need one character for the error message, set
- // szPathName[0] to the drive letter.
- //
- if (pOFI->szPath[1] == CHAR_COLON)
- {
- nDriveIndex = DiskAddedPreviously(pOFI->szPath[0], NULL);
- }
- else
- {
- nDriveIndex = DiskAddedPreviously(0, pOFI->szPath);
- }
- if (nDriveIndex == 0xFFFFFFFF)
- {
- nErrCode = ERROR_NO_DRIVE;
- }
- else
- {
- if (bUNCName)
- {
- nErrCode = ERROR_NO_DRIVE;
- }
- else
- {
- switch (GetDiskType(pOFI->szPath))
- {
- case ( DRIVE_REMOVABLE ) :
- {
- szPathName[0] = pOFI->szPath[0];
- nErrCode = ERROR_NO_DISK_IN_DRIVE;
- break;
- }
- case ( DRIVE_CDROM ) :
- {
- szPathName[0] = pOFI->szPath[0];
- nErrCode = ERROR_NO_DISK_IN_CDROM;
- break;
- }
- default :
- {
- nErrCode = ERROR_PATH_NOT_FOUND;
- }
- }
- }
- }
- }
- else
- {
- nErrCode = ERROR_FILE_NOT_FOUND;
- }
- //
- // If we don't set wNoRedraw here, then WM_ACTIVATE will set the
- // GetNetDrives event.
- //
- wNoRedraw |= 1;
- goto Warning;
- }
- if (PortName(pOFI->szPath + nFileOffset))
- {
- nErrCode = ERROR_PORTNAME;
- goto Warning;
- }
- #if 0
- //
- // Check if we've received a string in the form "C:filename.ext".
- // If we have, convert it to the form "C:.filename.ext". This is done
- // because the kernel will search the entire path, ignoring the drive
- // specification after the initial search. Making it include a slash
- // causes kernel to only search at that location.
- // Note: Only increment nExtOffset, not nFileOffset. This is done
- // because only nExtOffset is used later, and nFileOffset can then be
- // used at the Warning: label to determine if this hack has occurred,
- // and thus it can strip out the "." when putting out the error.
- //
- if ((nFileOffset == 2) && (pOFI->szPath[1] == CHAR_COLON))
- {
- lstrcpy(szWarning, pOFI->szPath + 2);
- lstrcpy(pOFI->szPath + 4, szWarning);
- pOFI->szPath[2] = CHAR_DOT;
- pOFI->szPath[3] = CHAR_BSLASH;
- nExtOffset += 2;
- }
- #endif
- //
- // Add the default extension unless filename ends with period or no
- // default extension exists. If the file exists, consider asking
- // permission to overwrite the file.
- //
- // NOTE: When no extension given, default extension is tried 1st.
- //
- if ( (nFileOffset != PARSE_DIRECTORYNAME) &&
- nExtOffset &&
- !pOFI->szPath[nExtOffset] &&
- pOFN->lpstrDefExt &&
- *pOFN->lpstrDefExt &&
- (((DWORD)nExtOffset + lstrlen(pOFN->lpstrDefExt)) < pOFN->nMaxFile) )
- {
- DWORD dwFileAttr;
- int nExtOffset2 = lstrlen(szPathName);
- bAddExt = TRUE;
- AppendExt(pOFI->szPath, pOFN->lpstrDefExt, FALSE);
- AppendExt(szPathName, pOFN->lpstrDefExt, FALSE);
- //
- // Directory may match default extension. Change to it as if it had
- // been typed in. A dir w/o the extension would have been switched
- // to in the logic above.
- //
- if ((dwFileAttr = GetFileAttributes(pOFI->szPath)) != 0xFFFFFFFF)
- {
- if (dwFileAttr & FILE_ATTRIBUTE_DIRECTORY)
- {
- if (ChangeDir(hDlg, szPathName, FALSE, TRUE) != CHANGEDIR_FAILED)
- {
- goto ChangedDir;
- }
- }
- }
- hFile = CreateFile( szPathName,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL );
- if (hFile == INVALID_HANDLE_VALUE)
- {
- nErrCode = GetLastError();
- //
- // Fix bug where progman cannot OK a file being browsed for new
- // item because it has Execute only permission.
- //
- if (nErrCode == ERROR_ACCESS_DENIED)
- {
- hFile = CreateFile( szPathName,
- GENERIC_EXECUTE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL );
- if (hFile == INVALID_HANDLE_VALUE)
- {
- nErrCode = GetLastError();
- }
- }
- }
- if (nErrCode == ERROR_SHARING_VIOLATION)
- {
- goto SharingViolationInquiry;
- }
- if (hFile != INVALID_HANDLE_VALUE)
- {
- if (!CloseHandle(hFile))
- {
- nErrCode = GetLastError();
- goto Warning;
- }
- AskPermission:
- //
- // Is the file read-only?
- //
- if (pOFN->Flags & OFN_NOREADONLYRETURN)
- {
- int nRet;
- if ((nRet = GetFileAttributes(szPathName)) != -1)
- {
- if (nRet & ATTR_READONLY)
- {
- nErrCode = ERROR_LAZY_READONLY;
- goto Warning;
- }
- }
- else
- {
- nErrCode = GetLastError();
- goto Warning;
- }
- }
- if ((bSave || (pOFN->Flags & OFN_NOREADONLYRETURN)) &&
- (nErrCode == ERROR_ACCESS_DENIED))
- {
- goto Warning;
- }
- if (pOFN->Flags & OFN_OVERWRITEPROMPT)
- {
- if (bSave && !FOkToWriteOver(hDlg, szPathName))
- {
- PostMessage( hDlg,
- WM_NEXTDLGCTL,
- (WPARAM)GetDlgItem(hDlg, edt1),
- (LPARAM)1L );
- return (FALSE);
- }
- }
- if (nErrCode == ERROR_SHARING_VIOLATION)
- {
- goto SharingViolationInquiry;
- }
- goto FileNameAccepted;
- }
- else
- {
- *(pOFI->szPath + nExtOffset) = CHAR_NULL;
- szPathName[nExtOffset2] = CHAR_NULL;
- }
- }
- else
- {
- //
- // Extension should not be added.
- //
- bAddExt = FALSE;
- }
- hFile = CreateFile( szPathName,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL );
- if (hFile == INVALID_HANDLE_VALUE)
- {
- nErrCode = GetLastError();
- //
- // Fix bug where progman cannot OK a file being browsed for new item
- // because it has Execute only permission.
- //
- if (nErrCode == ERROR_ACCESS_DENIED)
- {
- hFile = CreateFile( szPathName,
- GENERIC_EXECUTE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL );
- if (hFile == INVALID_HANDLE_VALUE)
- {
- nErrCode = GetLastError();
- }
- }
- }
- if (hFile != INVALID_HANDLE_VALUE)
- {
- if (!CloseHandle(hFile))
- {
- nErrCode = GetLastError();
- goto Warning;
- }
- goto AskPermission;
- }
- else
- {
- if ((nErrCode == ERROR_FILE_NOT_FOUND) ||
- (nErrCode == ERROR_PATH_NOT_FOUND))
- {
- //
- // Figure out if the default extension should be tacked on.
- //
- if (bAddExt)
- {
- AppendExt(pOFI->szPath, pOFN->lpstrDefExt, FALSE);
- AppendExt(szPathName, pOFN->lpstrDefExt, FALSE);
- }
- }
- else if (nErrCode == ERROR_SHARING_VIOLATION)
- {
- SharingViolationInquiry:
- //
- // If the app is "share aware", fall through.
- // Otherwise, ask the hook function.
- //
- if (!(pOFN->Flags & OFN_SHAREAWARE))
- {
- if (pOFN->lpfnHook)
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFN);
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- CHAR szPathNameA[MAX_FULLPATHNAME];
- RtlUnicodeToMultiByteSize(
- &cch,
- szPathName,
- lstrlenW(szPathName) * sizeof(TCHAR) );
- SHUnicodeToAnsi(szPathName,(LPSTR)&szPathNameA[0],cch + 1);
- cch = (DWORD)(*lpfnHook)( hDlg,
- msgSHAREVIOLATIONA,
- 0,
- (LONG_PTR)(LPSTR)szPathNameA );
- }
- else
- #endif
- {
- cch = (DWORD)(*lpfnHook)( hDlg,
- msgSHAREVIOLATIONW,
- 0,
- (LONG_PTR)szPathName );
- }
- if (cch == OFN_SHARENOWARN)
- {
- return (FALSE);
- }
- else if (cch != OFN_SHAREFALLTHROUGH)
- {
- goto Warning;
- }
- }
- else
- {
- goto Warning;
- }
- }
- goto FileNameAccepted;
- }
- if (!bSave)
- {
- if ((nErrCode == ERROR_FILE_NOT_FOUND) ||
- (nErrCode == ERROR_PATH_NOT_FOUND))
- {
- if (pOFN->Flags & OFN_FILEMUSTEXIST)
- {
- if (pOFN->Flags & OFN_CREATEPROMPT)
- {
- //
- // Don't alter pOFI->szPath.
- //
- bInChildDlg = TRUE;
- cch = (DWORD)CreateFileDlg(hDlg, pOFI->szPath);
- bInChildDlg = FALSE;
- if (cch == IDYES)
- {
- goto TestCreation;
- }
- else
- {
- return (FALSE);
- }
- }
- goto Warning;
- }
- }
- else
- {
- goto Warning;
- }
- }
- //
- // The file doesn't exist. Can it be created? This is needed because
- // there are many extended characters which are invalid that won't be
- // caught by ParseFile.
- // Two more good reasons: Write-protected disks & full disks.
- //
- // BUT, if they dont want the test creation, they can request that we
- // not do it using the OFN_NOTESTFILECREATE flag. If they want to
- // create files on a share that has create-but-no-modify privileges,
- // they should set this flag but be ready for failures that couldn't
- // be caught, such as no create privileges, invalid extended
- // characters, a full disk, etc.
- //
- TestCreation:
- if ((pOFN->Flags & OFN_PATHMUSTEXIST) &&
- (!(pOFN->Flags & OFN_NOTESTFILECREATE)))
- {
- //
- // Must use the FILE_FLAG_DELETE_ON_CLOSE flag so that the
- // file is automatically deleted when the handle is closed
- // (no need to call DeleteFile). This is necessary in the
- // event that the directory only has Add & Read access.
- // The CreateFile call will succeed, but the DeleteFile call
- // will fail. By adding the above flag to the CreateFile
- // call, it overrides the access rights and deletes the file
- // during the call to CloseHandle.
- //
- #ifdef WINNT
- hFile = CreateFile( szPathName,
- FILE_ADD_FILE,
- 0,
- NULL,
- CREATE_NEW,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
- NULL );
- #else
- // Win95/Memphis don't support FILE_ADD_FILE flag, use GENERIC_READ instead.
- hFile = CreateFile( szPathName,
- GENERIC_READ,
- 0,
- NULL,
- CREATE_NEW,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
- NULL );
- #endif
- if (hFile == INVALID_HANDLE_VALUE)
- {
- nErrCode = GetLastError();
- }
- if (hFile != INVALID_HANDLE_VALUE)
- {
- if (!CloseHandle(hFile))
- {
- nErrCode = GetLastError();
- goto Warning;
- }
- }
- else
- {
- //
- // Unable to create it.
- //
- // If it's not write-protection, a full disk,
- // network protection, or the user popping the drive door
- // open, assume that the filename is invalid.
- //
- if ( (nErrCode != ERROR_WRITE_PROTECT) &&
- (nErrCode != ERROR_CANNOT_MAKE) &&
- (nErrCode != ERROR_NETWORK_ACCESS_DENIED) &&
- (nErrCode != ERROR_ACCESS_DENIED) )
- {
- nErrCode = 0;
- }
- goto Warning;
- }
- }
- }
- FileNameAccepted:
- HourGlass(TRUE);
- lRet = ParseFile(szPathName, blfn, IS16BITWOWAPP(pOFN), FALSE);
- nFileOffset = (int)(SHORT)LOWORD(lRet);
- cch = (DWORD)HIWORD(lRet);
- pOFN->nFileOffset = (WORD)nFileOffset;
- if (nExtOffset || bAddExt)
- {
- pOFN->nFileExtension = LOWORD(cch);
- }
- else
- {
- pOFN->nFileExtension = 0;
- }
- pOFN->Flags &= ~OFN_EXTENSIONDIFFERENT;
- if (pOFN->lpstrDefExt && pOFN->nFileExtension)
- {
- TCHAR szPrivateExt[4];
- SHORT i;
- for (i = 0; i < 3; i++)
- {
- szPrivateExt[i] = *(pOFN->lpstrDefExt + i);
- }
- szPrivateExt[3] = CHAR_NULL;
- if (lstrcmpi(szPrivateExt, szPathName + cch))
- {
- pOFN->Flags |= OFN_EXTENSIONDIFFERENT;
- }
- }
- //
- // If we're called from wow, and the user hasn't changed
- // directories, shorten the path to abbreviated 8.3 format.
- //
- if (pOFN->Flags & OFN_NOLONGNAMES)
- {
- ShortenThePath(szPathName);
- //
- // If the path was shortened, the offset might have changed so
- // we must parse the file again.
- //
- lRet = ParseFile(szPathName, blfn, IS16BITWOWAPP(pOFN), FALSE);
- nFileOffset = (int)(SHORT)LOWORD(lRet);
- cch = (DWORD)HIWORD(lRet);
- //
- // When in Save dialog, the file may not exist yet, so the file
- // name cannot be shortened. So, we need to test if it's an
- // 8.3 filename and popup an error message if not.
- //
- if (bSave)
- {
- LPTSTR lptmp;
- LPTSTR lpExt = NULL;
- for (lptmp = szPathName + nFileOffset; *lptmp; lptmp++)
- {
- if (*lptmp == CHAR_DOT)
- {
- if (lpExt)
- {
- //
- // There's more than one dot in the file, so it is
- // invalid.
- //
- nErrCode = FNERR_INVALIDFILENAME;
- goto Warning;
- }
- lpExt = lptmp;
- }
- if (*lptmp == CHAR_SPACE)
- {
- nErrCode = FNERR_INVALIDFILENAME;
- goto Warning;
- }
- }
- if (lpExt)
- {
- //
- // There's an extension.
- //
- *lpExt = 0;
- }
- if ((lstrlen(szPathName + nFileOffset) > 8) ||
- (lpExt && lstrlen(lpExt + 1) > 3))
- {
- if (lpExt)
- {
- *lpExt = CHAR_DOT;
- }
- nErrCode = FNERR_INVALIDFILENAME;
- goto Warning;
- }
- if (lpExt)
- {
- *lpExt = CHAR_DOT;
- }
- }
- }
- if (pOFN->lpstrFile)
- {
- DWORD cchLen = lstrlen(szPathName);
- if (cchLen < pOFN->nMaxFile)
- {
- lstrcpy(pOFN->lpstrFile, szPathName);
- }
- else
- {
- //
- // Buffer is too small, so return the size of the buffer
- // required to hold the string.
- //
- // For single file requests, we will never go over 64K
- // because the filesystem is limited to 256.
- //
- #ifdef UNICODE
- pOFN->lpstrFile[0] = (TCHAR)LOWORD(cchLen);
- if (pOFN->nMaxFile >= 2)
- {
- pOFN->lpstrFile[1] = CHAR_NULL;
- }
- #else
- pOFN->lpstrFile[0] = LOBYTE(cchLen);
- pOFN->lpstrFile[1] = HIBYTE(cchLen);
- pOFN->lpstrFile[2] = CHAR_NULL;
- #endif
- }
- }
- //
- // File Title. Note that it's cut off at whatever the buffer length
- // is, so if the buffer is too small, no notice is given.
- //
- if (pOFN->lpstrFileTitle && pOFN->nMaxFileTitle)
- {
- cch = lstrlen(szPathName + nFileOffset);
- if (cch > pOFN->nMaxFileTitle)
- {
- szPathName[nFileOffset + pOFN->nMaxFileTitle - 1] = CHAR_NULL;
- }
- lstrcpy(pOFN->lpstrFileTitle, szPathName + nFileOffset);
- }
- if (pOFN->Flags | OFN_READONLY)
- {
- if (IsDlgButtonChecked(hDlg, chx1))
- {
- pOFN->Flags |= OFN_READONLY;
- }
- else
- {
- pOFN->Flags &= ~OFN_READONLY;
- }
- }
- return (TRUE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // MultiSelectOKButton
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL MultiSelectOKButton(
- HWND hDlg,
- POPENFILEINFO pOFI,
- BOOL bSave)
- {
- DWORD nErrCode;
- LPTSTR lpCurDir;
- LPTSTR lpchStart; // start of an individual filename
- LPTSTR lpchEnd; // end of an individual filename
- DWORD cch;
- HANDLE hFile;
- LPOPENFILENAME pOFN;
- BOOL EOS = FALSE; // end of string flag
- BOOL bRet;
- TCHAR szPathName[MAX_FULLPATHNAME - 1];
- LPCURDLG lpCurDlg;
- pOFN = pOFI->pOFN;
- //
- // Check for space for first full path element.
- //
- if(!(lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg)) ||
- !(lpCurDir = lpCurDlg->lpstrCurDir))
- {
- return (FALSE);
- }
- lstrcpy(pOFI->szPath, lpCurDir);
- if (StrChr(pOFI->szPath, CHAR_SPACE))
- {
- GetShortPathName(pOFI->szPath, pOFI->szPath, MAX_FULLPATHNAME);
- }
- if (!bCasePreserved)
- {
- CharLower(pOFI->szPath);
- }
- cch = (DWORD) ( lstrlen(pOFI->szPath) +
- sizeof(TCHAR) +
- SendDlgItemMessage(hDlg, edt1, WM_GETTEXTLENGTH, 0, 0L) );
- if (pOFN->lpstrFile)
- {
- if (cch > pOFN->nMaxFile)
- {
- //
- // Buffer is too small, so return the size of the buffer
- // required to hold the string (if possible).
- //
- if (pOFN->nMaxFile >= 3)
- {
- #ifdef UNICODE
- pOFN->lpstrFile[0] = (TCHAR)LOWORD(cch);
- pOFN->lpstrFile[1] = (TCHAR)HIWORD(cch);
- #else
- pOFN->lpstrFile[0] = (TCHAR)LOBYTE(cch);
- pOFN->lpstrFile[1] = (TCHAR)HIBYTE(cch);
- #endif
- pOFN->lpstrFile[2] = CHAR_NULL;
- }
- else
- {
- #ifdef UNICODE
- pOFN->lpstrFile[0] = (TCHAR)LOWORD(cch);
- if (pOFN->nMaxFile == 2)
- {
- pOFN->lpstrFile[1] = (TCHAR)HIWORD(cch);
- }
- #else
- pOFN->lpstrFile[0] = LOBYTE(cch);
- pOFN->lpstrFile[1] = HIBYTE(cch);
- pOFN->lpstrFile[2] = CHAR_NULL;
- #endif
- }
- }
- else
- {
- //
- // Copy in the full path as the first element.
- //
- lstrcpy(pOFN->lpstrFile, pOFI->szPath);
- lstrcat(pOFN->lpstrFile, TEXT(" "));
- //
- // Get the other files here.
- //
- cch = lstrlen(pOFN->lpstrFile);
- //
- // The path is guaranteed to be less than 64K (actually, < 260).
- //
- pOFN->nFileOffset = LOWORD(cch);
- lpchStart = pOFN->lpstrFile + cch;
- GetDlgItemText( hDlg,
- edt1,
- lpchStart,
- (int)(pOFN->nMaxFile - cch - 1) );
- while (*lpchStart == CHAR_SPACE)
- {
- lpchStart = CharNext(lpchStart);
- }
- if (*lpchStart == CHAR_NULL)
- {
- return (FALSE);
- }
- //
- // Go along file path looking for multiple filenames delimited by
- // spaces. For each filename found, try to open it to make sure
- // it's a valid file.
- //
- while (!EOS)
- {
- //
- // Find the end of the filename.
- //
- lpchEnd = lpchStart;
- while (*lpchEnd && *lpchEnd != CHAR_SPACE)
- {
- lpchEnd = CharNext(lpchEnd);
- }
- //
- // Mark the end of the filename with a NULL.
- //
- if (*lpchEnd == CHAR_SPACE)
- {
- *lpchEnd = CHAR_NULL;
- }
- else
- {
- //
- // Already NULL, found the end of the string.
- //
- EOS = TRUE;
- }
- //
- // Check that the filename is valid.
- //
- bRet = GetFullPathName( lpchStart,
- MAX_FULLPATHNAME,
- szPathName,
- NULL);
- if (!bRet)
- {
- nErrCode = ERROR_FILE_NOT_FOUND;
- goto MultiFileNotFound;
- }
- hFile = CreateFile( szPathName,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL );
- //
- // Fix bug where progman cannot OK a file being browsed for
- // new item because it has Execute only permission.
- //
- if (hFile == INVALID_HANDLE_VALUE)
- {
- nErrCode = GetLastError();
- if (nErrCode == ERROR_ACCESS_DENIED)
- {
- hFile = CreateFile( szPathName,
- GENERIC_EXECUTE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL );
- }
- else
- {
- goto MultiFileNotFound;
- }
- }
- if (hFile == INVALID_HANDLE_VALUE)
- {
- nErrCode = GetLastError();
- MultiFileNotFound:
- if ( ((pOFN->Flags & OFN_FILEMUSTEXIST) ||
- (nErrCode != ERROR_FILE_NOT_FOUND)) &&
- ((pOFN->Flags & OFN_PATHMUSTEXIST) ||
- (nErrCode != ERROR_PATH_NOT_FOUND)) &&
- (!(pOFN->Flags & OFN_SHAREAWARE) ||
- (nErrCode != ERROR_SHARING_VIOLATION)) )
- {
- if ( (nErrCode == ERROR_SHARING_VIOLATION) &&
- pOFN->lpfnHook )
- {
- LPOFNHOOKPROC lpfnHook = GETHOOKFN(pOFN);
- #ifdef UNICODE
- if (pOFI->ApiType == COMDLG_ANSI)
- {
- CHAR szPathNameA[MAX_FULLPATHNAME];
- RtlUnicodeToMultiByteSize(
- &cch,
- szPathName,
- lstrlenW(szPathName) * sizeof(TCHAR) );
- SHUnicodeToAnsi(szPathName,(LPSTR)&szPathNameA[0],cch + 1);
- cch = (DWORD)(*lpfnHook)( hDlg,
- msgSHAREVIOLATIONA,
- 0,
- (LONG_PTR)(LPSTR)szPathNameA );
- }
- else
- #endif
- {
- cch = (DWORD)(*lpfnHook)( hDlg,
- msgSHAREVIOLATIONW,
- 0,
- (LONG_PTR)szPathName );
- }
- if (cch == OFN_SHARENOWARN)
- {
- return (FALSE);
- }
- else if (cch == OFN_SHAREFALLTHROUGH)
- {
- goto EscapedThroughShare;
- }
- }
- else if (nErrCode == ERROR_ACCESS_DENIED)
- {
- szPathName[0] =
- (TCHAR)CharLower((LPTSTR)(DWORD)szPathName[0]);
- if (GetDiskType(szPathName) != DRIVE_REMOVABLE)
- {
- nErrCode = ERROR_NETWORK_ACCESS_DENIED;
- }
- }
- if ((nErrCode == ERROR_WRITE_PROTECT) ||
- (nErrCode == ERROR_CANNOT_MAKE) ||
- (nErrCode == ERROR_ACCESS_DENIED))
- {
- *lpchStart = szPathName[0];
- }
- MultiWarning:
- InvalidFileWarning(hDlg, lpchStart, nErrCode, 0);
- return (FALSE);
- }
- }
- EscapedThroughShare:
- if (hFile != INVALID_HANDLE_VALUE)
- {
- if (!CloseHandle(hFile))
- {
- nErrCode = GetLastError();
- goto MultiWarning;
- }
- if ((pOFN->Flags & OFN_NOREADONLYRETURN) &&
- (GetFileAttributes(szPathName) & FILE_ATTRIBUTE_READONLY))
- {
- nErrCode = ERROR_LAZY_READONLY;
- goto MultiWarning;
- }
- if ((bSave || (pOFN->Flags & OFN_NOREADONLYRETURN)) &&
- (nErrCode == ERROR_ACCESS_DENIED))
- {
- goto MultiWarning;
- }
- if (pOFN->Flags & OFN_OVERWRITEPROMPT)
- {
- if (bSave && !FOkToWriteOver(hDlg, szPathName))
- {
- PostMessage( hDlg,
- WM_NEXTDLGCTL,
- (WPARAM)GetDlgItem(hDlg, edt1),
- (LPARAM)1L );
- return (FALSE);
- }
- }
- }
- //
- // This file is valid, so check the next one.
- //
- if (!EOS)
- {
- lpchStart = lpchEnd + 1;
- while (*lpchStart == CHAR_SPACE)
- {
- lpchStart = CharNext(lpchStart);
- }
- if (*lpchStart == CHAR_NULL)
- {
- EOS = TRUE;
- }
- else
- {
- //
- // Not at end, replace NULL with SPACE.
- //
- *lpchEnd = CHAR_SPACE;
- }
- }
- }
- //
- // Limit String.
- //
- *lpchEnd = CHAR_NULL;
- }
- }
- //
- // This doesn't really mean anything for multiselection.
- //
- pOFN->nFileExtension = 0;
- pOFN->nFilterIndex = (int) SendDlgItemMessage(hDlg, cmb1, CB_GETCURSEL, 0, 0L);
- return (TRUE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // dwOKSubclass
- //
- // Simulates a double click if the user presses OK with the mouse
- // and the focus was on the directory listbox.
- //
- // The problem is that the UITF demands that when the directory
- // listbox loses the focus, the selected directory should return
- // to the current directory. But when the user changes the item
- // selected with a single click, and then clicks the OK button to
- // have the change take effect, the focus is lost before the OK button
- // knows it was pressed. By setting the global flag bChangeDir
- // when the directory listbox loses the focus and clearing it when
- // the OK button loses the focus, we can check whether a mouse
- // click should update the directory.
- //
- // Returns: Return value from default listbox proceedure.
- //
- ////////////////////////////////////////////////////////////////////////////
- LRESULT WINAPI dwOKSubclass(
- HWND hOK,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- HANDLE hDlg;
- POPENFILEINFO pOFI;
- if (msg == WM_KILLFOCUS)
- {
- if (bChangeDir)
- {
- if (pOFI = (POPENFILEINFO)GetProp(hDlg = GetParent(hOK), FILEPROP))
- {
- SendDlgItemMessage( hDlg,
- lst2,
- LB_SETCURSEL,
- (WPARAM)(pOFI->idirSub - 1),
- 0L );
- }
- bChangeDir = FALSE;
- }
- }
- return (CallWindowProc(lpOKProc, hOK, msg, wParam, lParam));
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // dwLBSubclass
- //
- // Simulates a double click if the user presses OK with the mouse.
- //
- // The problem is that the UITF demands that when the directory
- // listbox loses the focus, the selected directory should return
- // to the current directory. But when the user changes the item
- // selected with a single click, and then clicks the OK button to
- // have the change take effect, the focus is lost before the OK button
- // knows it was pressed. By simulating a double click, the change
- // takes place.
- //
- // Returns: Return value from default listbox proceedure.
- //
- ////////////////////////////////////////////////////////////////////////////
- LRESULT WINAPI dwLBSubclass(
- HWND hLB,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- HANDLE hDlg;
- POPENFILEINFO pOFI;
- if (msg == WM_KILLFOCUS)
- {
- hDlg = GetParent(hLB);
- bChangeDir = (GetDlgItem(hDlg, IDOK) == (HWND)wParam) ? TRUE : FALSE;
- if (!bChangeDir)
- {
- if (pOFI = (POPENFILEINFO)GetProp(hDlg, FILEPROP))
- {
- SendMessage( hLB,
- LB_SETCURSEL,
- (WPARAM)(pOFI->idirSub - 1),
- 0L );
- }
- }
- }
- return (CallWindowProc(lpLBProc, hLB, msg, wParam, lParam));
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // InvalidFileWarning
- //
- ////////////////////////////////////////////////////////////////////////////
- int InvalidFileWarning(
- HWND hDlg,
- LPTSTR szFile,
- DWORD wErrCode,
- UINT mbType)
- {
- SHORT isz;
- BOOL bDriveLetter = FALSE;
- int nRet = 0;
- if (lstrlen(szFile) > TOOLONGLIMIT)
- {
- *(szFile + TOOLONGLIMIT) = CHAR_NULL;
- }
- switch (wErrCode)
- {
- case ( ERROR_NO_DISK_IN_DRIVE ) :
- {
- isz = iszNoDiskInDrive;
- bDriveLetter = TRUE;
- break;
- }
- case ( ERROR_NO_DISK_IN_CDROM ) :
- {
- isz = iszNoDiskInCDRom;
- bDriveLetter = TRUE;
- break;
- }
- case ( ERROR_NO_DRIVE ) :
- {
- isz = iszDriveDoesNotExist;
- bDriveLetter = TRUE;
- break;
- }
- case ( ERROR_TOO_MANY_OPEN_FILES ) :
- {
- isz = iszNoFileHandles;
- break;
- }
- case ( ERROR_PATH_NOT_FOUND ) :
- {
- isz = iszPathNotFound;
- break;
- }
- case ( ERROR_FILE_NOT_FOUND ) :
- {
- isz = iszFileNotFound;
- break;
- }
- case ( ERROR_CANNOT_MAKE ) :
- case ( ERROR_DISK_FULL ) :
- {
- isz = iszDiskFull;
- bDriveLetter = TRUE;
- break;
- }
- case ( ERROR_WRITE_PROTECT ) :
- {
- isz = iszWriteProtection;
- bDriveLetter = TRUE;
- break;
- }
- case ( ERROR_SHARING_VIOLATION ) :
- {
- isz = iszSharingViolation;
- break;
- }
- case ( ERROR_CREATE_NO_MODIFY ) :
- {
- isz = iszCreateNoModify;
- break;
- }
- case ( ERROR_NETWORK_ACCESS_DENIED ) :
- {
- isz = iszNetworkAccessDenied;
- break;
- }
- case ( ERROR_PORTNAME ) :
- {
- isz = iszPortName;
- break;
- }
- case ( ERROR_LAZY_READONLY ) :
- {
- isz = iszReadOnly;
- break;
- }
- case ( ERROR_DIR_ACCESS_DENIED ) :
- {
- isz = iszDirAccessDenied;
- break;
- }
- case ( ERROR_FILE_ACCESS_DENIED ) :
- case ( ERROR_ACCESS_DENIED ) :
- {
- isz = iszFileAccessDenied;
- break;
- }
- case ( ERROR_UNRECOGNIZED_VOLUME ) :
- {
- FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS |
- FORMAT_MESSAGE_MAX_WIDTH_MASK,
- NULL,
- wErrCode,
- GetUserDefaultLCID(),
- szWarning,
- WARNINGMSGLENGTH,
- NULL );
- goto DisplayError;
- }
- default :
- {
- isz = iszInvalidFileName;
- break;
- }
- }
- if (!CDLoadString( g_hinst,
- isz,
- szCaption,
- WARNINGMSGLENGTH ))
- {
- wsprintf( szWarning,
- TEXT("Error occurred, but error resource cannot be loaded.") );
- }
- else
- {
- wsprintf( szWarning,
- szCaption,
- bDriveLetter ? (LPTSTR)(CHAR)*szFile : szFile );
- DisplayError:
- GetWindowText(hDlg, szCaption, WARNINGMSGLENGTH);
- if (!mbType)
- {
- mbType = MB_OK | MB_ICONEXCLAMATION;
- }
- nRet = MessageBox(hDlg, szWarning, szCaption, mbType);
- }
- if (isz == iszInvalidFileName)
- {
- PostMessage( hDlg,
- WM_NEXTDLGCTL,
- (WPARAM)GetDlgItem(hDlg, edt1),
- (LPARAM)1L );
- }
- return (nRet);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // MeasureItem
- //
- ////////////////////////////////////////////////////////////////////////////
- VOID MeasureItem(
- HWND hDlg,
- LPMEASUREITEMSTRUCT mis)
- {
- if (!dyItem)
- {
- HDC hDC = GetDC(hDlg);
- TEXTMETRIC TM;
- HANDLE hFont;
- hFont = (HANDLE)SendMessage(hDlg, WM_GETFONT, 0, 0L);
- if (!hFont)
- {
- hFont = GetStockObject(SYSTEM_FONT);
- }
- hFont = SelectObject(hDC, hFont);
- GetTextMetrics(hDC, &TM);
- SelectObject(hDC, hFont);
- ReleaseDC(hDlg, hDC);
- dyText = TM.tmHeight;
- dyItem = max(dyDirDrive, dyText);
- }
- if (mis->CtlID == lst1)
- {
- mis->itemHeight = dyText;
- }
- else
- {
- mis->itemHeight = dyItem;
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Signum
- //
- // Returns the sign of an integer:
- // -1 if integer < 0
- // 0 if integer = 0
- // 1 if integer > 0
- //
- // Note: Signum *could* be defined as an inline macro, but that causes
- // the C compiler to disable Loop optimization, Global register
- // optimization, and Global optimizations for common subexpressions
- // in any function that the macro would appear. The cost of a call
- // to the function seemed worth the optimizations.
- //
- ////////////////////////////////////////////////////////////////////////////
- int Signum(
- int nTest)
- {
- return ((nTest == 0) ? 0 : (nTest > 0) ? 1 : -1);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // DrawItem
- //
- // Draws the drive/directory pictures in the respective combo list boxes.
- //
- // lst1 is listbox for files
- // lst2 is listbox for directories
- // cmb1 is combobox for filters
- // cmb2 is combobox for drives
- //
- ////////////////////////////////////////////////////////////////////////////
- VOID DrawItem(
- POPENFILEINFO pOFI,
- HWND hDlg,
- WPARAM wParam,
- LPDRAWITEMSTRUCT lpdis,
- BOOL bSave)
- {
- HDC hdcList;
- RECT rc;
- // RECT rcCmb2;
- TCHAR szText[MAX_FULLPATHNAME + 1];
- int dxAcross;
- LONG nHeight;
- LONG rgbBack, rgbText, rgbOldBack, rgbOldText;
- SHORT nShift = 1; // to shift directories right in lst2
- BOOL bSel;
- int BltItem;
- int nBackMode;
- if ((int)lpdis->itemID < 0)
- {
- DefWindowProc(hDlg, WM_DRAWITEM, wParam, (LPARAM)lpdis);
- return;
- }
- *szText = CHAR_NULL;
- if (lpdis->CtlID != lst1 && lpdis->CtlID != lst2 && lpdis->CtlID != cmb2)
- {
- return;
- }
- if (!pOFI)
- {
- return;
- }
- hdcList = lpdis->hDC;
- if (lpdis->CtlID != cmb2)
- {
- SendDlgItemMessage( hDlg,
- (int)lpdis->CtlID,
- LB_GETTEXT ,
- (WPARAM)lpdis->itemID,
- (LONG_PTR)szText );
- if (*szText == 0)
- {
- //
- // If empty listing.
- //
- DefWindowProc(hDlg, WM_DRAWITEM, wParam, (LONG_PTR)lpdis);
- return;
- }
- if (!bCasePreserved)
- {
- CharLower(szText);
- }
- }
- nHeight = (lpdis->CtlID == lst1) ? dyText : dyItem;
- CopyRect((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
- rc.bottom = rc.top + nHeight;
- if (bSave && (lpdis->CtlID == lst1))
- {
- rgbBack = rgbWindowColor;
- rgbText = rgbGrayText;
- }
- else
- {
- //
- // Careful checking of bSel is needed here. Since the file
- // listbox (lst1) can allow multiselect, only ODS_SELECTED needs
- // to be set. But for the directory listbox (lst2), ODS_FOCUS
- // also needs to be set.
- //
- bSel = (lpdis->itemState & (ODS_SELECTED | ODS_FOCUS));
- if ((bSel & ODS_SELECTED) &&
- ((lpdis->CtlID != lst2) || (bSel & ODS_FOCUS)))
- {
- rgbBack = rgbHiliteColor;
- rgbText = rgbHiliteText;
- }
- else
- {
- rgbBack = rgbWindowColor;
- rgbText = rgbWindowText;
- }
- }
- rgbOldBack = SetBkColor(hdcList, rgbBack);
- rgbOldText = SetTextColor(hdcList, rgbText);
- //
- // Drives -- text is now in UI style, c: VolumeName/Server-Sharename.
- //
- if (lpdis->CtlID == cmb2)
- {
- HANDLE hCmb2 = GetDlgItem(hDlg, cmb2);
- dxAcross = dxDirDrive / BMPHIOFFSET;
- BltItem = (int) SendMessage(hCmb2, CB_GETITEMDATA, lpdis->itemID, 0);
- SendMessage(hCmb2, CB_GETLBTEXT, lpdis->itemID, (LPARAM)szText);
- if (bSel & ODS_SELECTED)
- {
- BltItem += BMPHIOFFSET;
- }
- }
- else if (lpdis->CtlID == lst2)
- {
- //
- // Directories.
- //
- dxAcross = dxDirDrive / BMPHIOFFSET;
- if (lpdis->itemID > pOFI->idirSub)
- {
- nShift = (SHORT)pOFI->idirSub;
- }
- else
- {
- nShift = (SHORT)lpdis->itemID;
- }
- //
- // Must be at least 1.
- //
- nShift++;
- BltItem = 1 + Signum(lpdis->itemID + 1 - pOFI->idirSub);
- if (bSel & ODS_FOCUS)
- {
- BltItem += BMPHIOFFSET;
- }
- }
- else if (lpdis->CtlID == lst1)
- {
- //
- // Prep for TextOut below.
- //
- dxAcross = -dxSpace;
- }
- if (bSave && (lpdis->CtlID == lst1) && !rgbText)
- {
- HBRUSH hBrush = CreateSolidBrush(rgbBack);
- HBRUSH hOldBrush;
- nBackMode = SetBkMode(hdcList, TRANSPARENT);
- hOldBrush = SelectObject( lpdis->hDC,
- hBrush
- ? hBrush
- : GetStockObject(WHITE_BRUSH) );
- FillRect(lpdis->hDC, (LPRECT)(&(lpdis->rcItem)), hBrush);
- SelectObject(lpdis->hDC, hOldBrush);
- if (hBrush)
- {
- DeleteObject(hBrush);
- }
- GrayString( lpdis->hDC,
- GetStockObject(BLACK_BRUSH),
- NULL,
- (LPARAM)szText,
- 0,
- lpdis->rcItem.left + dxSpace,
- lpdis->rcItem.top,
- 0,
- 0 );
- SetBkMode(hdcList, nBackMode);
- }
- #if 0
- else if (lpdis->CtlID == cmb2)
- {
- rcCmb2.right = rc.right;
- rcCmb2.left = rc.left + (WORD)(dxSpace + dxAcross) + (dxSpace * nShift);
- rcCmb2.top = rc.top + (dyItem - dyText) / 2;
- rcCmb2.bottom = rc.top + nHeight;
- DrawText( hdcList,
- szText,
- -1,
- &rcCmb2,
- DT_LEFT | DT_EXPANDTABS | DT_NOPREFIX );
- }
- #endif
- else
- {
- //
- // Draw the name.
- //
- ExtTextOut( hdcList,
- rc.left + (WORD)(dxSpace + dxAcross) + dxSpace * nShift,
- rc.top + (nHeight - dyText) / 2,
- ETO_OPAQUE | ETO_CLIPPED,
- (LPRECT)&rc,
- szText,
- lstrlen(szText),
- NULL );
- }
- //
- // Draw the picture.
- //
- if (lpdis->CtlID != lst1)
- {
- BitBlt( hdcList,
- rc.left + dxSpace * nShift,
- rc.top + (dyItem - dyDirDrive) / 2,
- dxAcross,
- dyDirDrive,
- hdcMemory,
- BltItem * dxAcross,
- 0,
- SRCCOPY );
- }
- SetTextColor(hdcList, rgbOldText);
- SetBkColor(hdcList, rgbBack);
- if (lpdis->itemState & ODS_FOCUS)
- {
- DrawFocusRect(hdcList, (LPRECT)&lpdis->rcItem);
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // SpacesExist
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL SpacesExist(
- LPTSTR szFileName)
- {
- while (*szFileName)
- {
- if (*szFileName == CHAR_SPACE)
- {
- return (TRUE);
- }
- else
- {
- szFileName++;
- }
- }
- return (FALSE);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // StripFileName
- //
- // Removes all but the filename from editbox contents.
- // This is to be called before the user makes directory or drive
- // changes by selecting them instead of typing them.
- //
- ////////////////////////////////////////////////////////////////////////////
- void StripFileName(
- HANDLE hDlg,
- BOOL bWowApp)
- {
- TCHAR szText[MAX_FULLPATHNAME];
- SHORT nFileOffset, cb;
- if (GetDlgItemText(hDlg, edt1, szText, MAX_FULLPATHNAME - 1))
- {
- DWORD lRet;
- lRet = ParseFile(szText, IsLFNDriveX(hDlg, szText), bWowApp, FALSE);
- nFileOffset = LOWORD(lRet);
- cb = HIWORD(lRet);
- if (nFileOffset < 0)
- {
- //
- // If there was a parsing error, check for CHAR_SEMICOLON
- // delimeter.
- //
- if (szText[cb] == CHAR_SEMICOLON)
- {
- szText[cb] = CHAR_NULL;
- nFileOffset = (WORD)ParseFile( szText,
- IsLFNDriveX(hDlg, szText),
- bWowApp,
- FALSE );
- szText[cb] = CHAR_SEMICOLON;
- if (nFileOffset < 0)
- {
- //
- // Still trouble, so Exit.
- //
- szText[0] = CHAR_NULL;
- }
- }
- else
- {
- szText[0] = CHAR_NULL;
- }
- }
- if (nFileOffset > 0)
- {
- lstrcpy(szText, (LPTSTR)(szText + nFileOffset));
- }
- if (nFileOffset)
- {
- SetDlgItemText(hDlg, edt1, szText);
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // lstrtok
- //
- ////////////////////////////////////////////////////////////////////////////
- LPTSTR lstrtok(
- LPTSTR lpStr,
- LPCTSTR lpDelim)
- {
- static LPTSTR lpString;
- LPTSTR lpRetVal, lpTemp;
- //
- // If we are passed new string skip leading delimiters.
- //
- if (lpStr)
- {
- lpString = lpStr;
- while (*lpString && StrChr(lpDelim, *lpString))
- {
- lpString = CharNext(lpString);
- }
- }
- //
- // If there are no more tokens, return NULL.
- //
- if (!*lpString)
- {
- return (CHAR_NULL);
- }
- //
- // Save head of token.
- //
- lpRetVal = lpString;
- //
- // Find delimiter or end of string.
- //
- while (*lpString && !StrChr(lpDelim, *lpString))
- {
- lpString = CharNext(lpString);
- }
- //
- // If we found a delimiter insert string terminator and skip.
- //
- if (*lpString)
- {
- lpTemp = CharNext(lpString);
- *lpString = CHAR_NULL;
- lpString = lpTemp;
- }
- //
- // Return token.
- //
- return (lpRetVal);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // ChopText
- //
- ////////////////////////////////////////////////////////////////////////////
- LPTSTR ChopText(
- HWND hwndDlg,
- int idStatic,
- LPTSTR lpch)
- {
- RECT rc;
- register int cxField;
- BOOL fChop = FALSE;
- HWND hwndStatic;
- HDC hdc;
- TCHAR chDrv;
- HANDLE hOldFont;
- LPTSTR lpstrStart = lpch;
- SIZE Size;
- BOOL bRet;
- //
- // Get length of static field.
- //
- hwndStatic = GetDlgItem(hwndDlg, idStatic);
- GetClientRect(hwndStatic, (LPRECT)&rc);
- cxField = rc.right - rc.left;
- //
- // Chop characters off front end of text until short enough.
- //
- hdc = GetDC(hwndStatic);
- hOldFont = NULL;
- while ((bRet = GetTextExtentPoint(hdc, lpch, lstrlen(lpch), &Size)) &&
- (cxField < Size.cx))
- {
- if (!fChop)
- {
- chDrv = *lpch;
- //
- // Proportional font support.
- //
- if (bRet = GetTextExtentPoint(hdc, lpch, 7, &Size))
- {
- cxField -= Size.cx;
- }
- else
- {
- break;
- }
- if (cxField <= 0)
- {
- break;
- }
- lpch += 7;
- }
- while (*lpch && (!ISBACKSLASH_P(lpstrStart, lpch)))
- {
- lpch++;
- }
- //Skip the backslash
- lpch++;
- fChop = TRUE;
- }
- ReleaseDC(hwndStatic, hdc);
- //
- // If any characters chopped off, replace first three characters in
- // remaining text string with ellipsis.
- //
- if (fChop)
- {
- //Skip back to include the backslash
- lpch--;
- *--lpch = CHAR_DOT;
- *--lpch = CHAR_DOT;
- *--lpch = CHAR_DOT;
- *--lpch = *(lpstrStart + 2);
- *--lpch = *(lpstrStart + 1);
- *--lpch = *lpstrStart;
- }
- return (lpch);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // FillOutPath
- //
- // Fills out lst2 given that the current directory has been set.
- //
- // Returns: TRUE if they DO NOT match
- // FALSE if match
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL FillOutPath(
- HWND hList,
- POPENFILEINFO pOFI)
- {
- TCHAR szPath[CCHNETPATH];
- LPTSTR lpCurDir;
- LPTSTR lpB, lpF;
- TCHAR wc;
- int cchPathOffset;
- LPCURDLG lpCurDlg;
- if(!(lpCurDlg = (LPCURDLG)TlsGetValue(g_tlsiCurDlg)) ||
- !(lpCurDir = lpCurDlg->lpstrCurDir))
- {
- return (FALSE);
- }
- lpF = szPath;
- lstrcpy(lpF, lpCurDir);
- //
- // Wow apps started from lfn dirs will set the current directory to an
- // lfn, but only in the case where it is less than 8 chars.
- //
- if (pOFI->pOFN->Flags & OFN_NOLONGNAMES)
- {
- ShortenThePath(lpF);
- }
- *lpF = (TCHAR)CharLower((LPTSTR)*lpF);
- cchPathOffset = GetPathOffset(lpF);
- if (cchPathOffset == -1)
- {
- cchPathOffset = 0;
- }
- lpB = (lpF + cchPathOffset);
- //
- // Hack to retain Winball display functionality.
- // Drived disks are displayed as C: (the root dir).
- // whereas unc disks are displayed as \servershare (the disk).
- // Hence, extend display of drived disks by one char.
- //
- if (*(lpF + 1) == CHAR_COLON)
- {
- wc = *(++lpB);
- *lpB = CHAR_NULL;
- }
- else