home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / crypto / cfiler / fillfile.c < prev    next >
C/C++ Source or Header  |  1997-10-13  |  21KB  |  717 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright 1996-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. // FILLFILE.C
  13.  
  14. #include "cfiler.h"
  15.  
  16. extern HANDLE               ghDrvThread;
  17. extern HWND                   ghwndDrv;
  18.  
  19. /********************************************************************************\
  20. * FillFile()
  21. *
  22. * in parameters
  23. * lpCInfo - instance data for drive child
  24. * hwnd - HWND specified by caller
  25. *
  26. * purpose:
  27. * Fills the file listbox with strings constructed from the contents of the 
  28. * directory that is highlighted in the directory listbox.
  29. * This is accomplished by building a file string table with hidden and displayed
  30. * string pairs. The hidden strings are the full pathnames as they exist on the
  31. * disk. The displayed strings are specially formatted strings containing file
  32. * and directory names to be displayed in the owner-draw listbox. The listbox
  33. * knows how to appropriately draw these file and directory names because the
  34. * strings have some special characters at the beginning. Once the string table
  35. * has been constructed, a function called TableSend is called, which generates
  36. * LB_ADDSTRING messages to the listbox, one for each displayed string in the
  37. * table.
  38. *
  39. * returns:
  40. * TRUE if successful
  41. * FALSE if unsuccessful
  42. \********************************************************************************/
  43.  
  44. BOOL FillFile(LPCINFO lpCInfo, HWND hwnd) {
  45.     BOOL                bHasSignature = FALSE;
  46.     BOOL                fNextFile = TRUE;
  47.     BOOL                fSearchFlag = TRUE;
  48.     DWORD                dwLastError = ERROR_SUCCESS;
  49.     HANDLE                hFindFile;
  50.     HANDLE                hFileRead;
  51.     INT                    i;
  52.     TCHAR                szDecryptedName[PATH_SIZE];
  53.     TCHAR                szFileName[PATH_SIZE];
  54.     TCHAR                szFind[PATH_SIZE];
  55.     TCHAR               szFiles[PATH_SIZE];
  56.     TCHAR                szBuf[PATH_SIZE];
  57.     WIN32_FIND_DATA        FindFileData;
  58.     LONG                lIndex;
  59.     TABLE                sigtable;
  60.  
  61.     if (!lpCInfo) {
  62.         ErrorMsg(TEXT("FillFile: lpCInfo is NULL."));
  63.         return FALSE;
  64.     }
  65.     
  66.     if( WaitForSingleObject(lpCInfo->hFileMutex, MUTEX_TIMEOUT) 
  67.                                                     == WAIT_TIMEOUT) {
  68.         ErrorMsg(TEXT("FillFile: File LB Mutex Timeout."));
  69.         return 0;
  70.     }
  71.                  
  72.     TableFree(lpCInfo->FileTable);
  73.  
  74.     lpCInfo->FileTable = TableNew();
  75.                    
  76.     if (!lpCInfo->FileTable) {
  77.         ErrorMsg(TEXT("MM_FILLFILE: TableNew failed."));
  78.         return 0;
  79.     }
  80.                                
  81.     SendMessage(lpCInfo->hFileLB, LB_RESETCONTENT, (WPARAM)NULL, (LPARAM)NULL);
  82.  
  83.     // Put the full pathname of the directory into szFind
  84.     // by accessing the directory string table.
  85.                 
  86.     lIndex = SendMessage( lpCInfo->hDirLB, LB_GETCARETINDEX,
  87.               (WPARAM)NULL, (LPARAM)NULL );
  88.                           
  89.     if (!TableGetHidden(lpCInfo->DirTable, lIndex, szFind)) {
  90.         ErrorMsg(TEXT("FillFile: TableGetHidden failed."));
  91.         return 0;
  92.     }
  93.            
  94.     // if szFind has a '\' append a * otherwise append '\*'
  95.  
  96.     if (szFind[lstrlen(szFind) - 1] == TEXT('\\')) 
  97.         szFind[lstrlen(szFind) - 1] = TEXT('\0');
  98.                   
  99.     lstrcpy(szFiles, szFind);
  100.                 
  101.     lstrcat(szFind, TEXT("\\*"));
  102.                 
  103.     if ((hFindFile = FindFirstFile(szFind, &FindFileData)) 
  104.                                                             == INVALID_HANDLE_VALUE) {
  105.         ReleaseMutex(lpCInfo->hFileMutex);
  106.         ErrorMsg(TEXT("FillFile: FindFirstFile failed."));
  107.         ReleaseMutex(lpCInfo->hFileMutex);
  108.         return 0;
  109.     }
  110.             
  111.     sigtable = TableNew();
  112.     
  113.     if (!sigtable) {
  114.         ErrorMsg(TEXT("FillFile: TableNew failed."));
  115.         return 0;
  116.     }
  117.     
  118.     BuildSigTable(sigtable);
  119.     
  120.     // Loop through, calling FindNextFiles until no more files are left.
  121.                     
  122.     for (i = 0; fNextFile || dwLastError != ERROR_NO_MORE_FILES; i++) {
  123.         lstrcpy(szFileName, szFiles);
  124.         lstrcat(szFileName, TEXT("\\"));
  125.         lstrcat(szFileName, FindFileData.cFileName);
  126.         bHasSignature = FALSE;
  127.                         
  128.         // If szFileName is not a directory, check if it has a signature.
  129.                     
  130.         if (!CFilerIsDirectory(szFileName))
  131.             HasSignature(szFileName, sigtable, &bHasSignature);
  132.                     
  133.         if (IsEncrypted(szFileName)) {
  134.             BOOL fIsValidEncryptedFile = TRUE;
  135.                     
  136.             if (!CFilerIsDirectory(szFileName)) {
  137.                 if (!GetDecryptedFileName(hwnd, szFileName, szDecryptedName, &hFileRead)) {
  138.                     fIsValidEncryptedFile = FALSE;
  139.                     lstrcpy(szBuf, TEXT("\0"));
  140.                 }
  141.                 CloseHandle(hFileRead);
  142.             }
  143.             else
  144.                 GetDecryptedDirName(hwnd, szFileName, szDecryptedName, 0, &hFileRead);
  145.  
  146.             if (fIsValidEncryptedFile) {
  147.                 if (!bHasSignature) 
  148.                 // '|' indicates to the the owner-draw listbox
  149.                 // an encrypted file or directory
  150.                 // This is not unwholesome since '|' is not a legal
  151.                 // character for a file or directory identifier.
  152.                     lstrcpy(szBuf, TEXT("|")); 
  153.                 else if (bHasSignature) 
  154.                 // '>' indicates an encrypted file that has been signed.
  155.                 // This is not unwholesome since '>' is not a legal character
  156.                 // for a file or directory identifier.
  157.                     lstrcpy(szBuf, TEXT(">")); 
  158.             }                
  159.         
  160.             lstrcat(szBuf, szDecryptedName);
  161.                         
  162.             // add to string table.
  163.  
  164.             if (IsLegalToAdd(FindFileData.cFileName)) {
  165.                  if (!TableAdd(lpCInfo->FileTable, FindFileData.cFileName, szBuf)) {
  166.                     ErrorMsg(TEXT("FillFile: TableAdd failed."));
  167.                     return FALSE;
  168.                 }
  169.             }                
  170.         }
  171.         else {
  172.         // Not encrypted
  173.                 
  174.             if (CFilerIsDirectory(szFileName)) {
  175.                             
  176.                 // For directories, enclose the directory name with brackets 
  177.                 // before inserting into string table.
  178.                             
  179.                 lstrcpy(szBuf, TEXT("["));
  180.                 lstrcat(szBuf, FindFileData.cFileName);
  181.                 lstrcat(szBuf, TEXT("]"));
  182.                             
  183.                 // Add directory name to string table.
  184.  
  185.                 if (IsLegalToAdd(FindFileData.cFileName)) {
  186.                     if (!TableAdd(lpCInfo->FileTable, szBuf, szBuf)) {
  187.                         ErrorMsg(TEXT("FillFile: TableAdd failed."));
  188.                         return FALSE;
  189.                     }
  190.                 }
  191.             }
  192.             else if (!CFilerIsDirectory(szFileName)) {
  193.  
  194.             // Not a directory and not encrypted
  195.  
  196.                 if (!bHasSignature)
  197.                     lstrcpy(szBuf, FindFileData.cFileName);
  198.                 else if (bHasSignature) {
  199.                 // ';' indicates a signed file. This is
  200.                 // not unwholesome since ';' is not a legal
  201.                 // character for a filename.
  202.                     lstrcpy(szBuf, TEXT(";"));
  203.                     lstrcat(szBuf, FindFileData.cFileName);
  204.                 }                            
  205.                 // Add filename to string table.
  206.                             
  207.                 if (IsLegalToAdd(FindFileData.cFileName)) {
  208.                      if (!TableAdd(lpCInfo->FileTable, FindFileData.cFileName, szBuf)) {
  209.                         ErrorMsg(TEXT("FillFile: TableAdd failed."));
  210.                         return FALSE;
  211.                     }
  212.                 }
  213.             }
  214.         }
  215.             
  216.         fNextFile = FindNextFile(hFindFile, &FindFileData);
  217.  
  218.         dwLastError = GetLastError();
  219.     }
  220.                 
  221.     // sort the file string table on its displayed members
  222.     // using the same string compare routine
  223.     // that the owner-draw listbox uses.
  224.                 
  225.     if (!TableSort(lpCInfo->FileTable, CFilerlstrcmp)) {
  226.         ErrorMsg(TEXT("FillFile: selection failed."));
  227.         return 0;
  228.     }
  229.             
  230.     // send all of the displayed members of the file string table
  231.     // to the owner-draw listbox.
  232.     // It does not matter in what order they are sent since the
  233.     // owner-draw listbox will sort them anyway.
  234.  
  235.     if (GetSize(lpCInfo->FileTable) && !TableSend(lpCInfo->FileTable, lpCInfo->hFileLB)) {
  236.         ErrorMsg(TEXT("FillFile: TableSend failed."));
  237.         return 0;
  238.     }
  239.             
  240.     //
  241.     //  Set selection to first file.
  242.     //
  243.     if (GetSize(lpCInfo->FileTable)) {
  244.         if(SendMessage(lpCInfo->hFileLB, LB_SETSEL, (WPARAM)TRUE, (LPARAM)0) == LB_ERR) {
  245.             ErrorMsg(TEXT("FillFile:  Listbox selection failure."));
  246.             ReleaseMutex( lpCInfo->hFileMutex );
  247.             return 0;
  248.         }
  249.     }
  250.  
  251.     if (!SetWindowText(lpCInfo->hTextWnd, lpCInfo->CaptionBarText)) {
  252.         ErrorMsg(TEXT("FillFile: SetWindowText failed."));
  253.         return FALSE;
  254.     }
  255.  
  256.     TableFree(sigtable);
  257.  
  258.     ReleaseMutex( lpCInfo->hFileMutex );
  259.  
  260.     FindClose(hFindFile);
  261.  
  262.     return TRUE;
  263. }
  264.  
  265. /************************************************************************\
  266. * BuildSigTable()
  267. *
  268. * input:
  269. * sigtable - pointer to an empty string table
  270. *
  271. * purpose:
  272. * Builds a string table with displayed fields containing
  273. * the filenames of all the files in the \sig directory on the
  274. * same drive as the system directory.
  275. *
  276. * returns
  277. * TRUE if successful
  278. * FALSE if unsuccessful
  279. \************************************************************************/
  280.  
  281. BOOL BuildSigTable(TABLE sigtable)
  282. {
  283.     WIN32_FIND_DATA FindFileData;
  284.     HANDLE hFindFile;
  285.     TCHAR szFiles[PATH_SIZE];
  286.     TCHAR szFileName[PATH_SIZE];
  287.     TCHAR szSystemDirectory[PATH_SIZE];
  288.     TCHAR szSigDir[PATH_SIZE];
  289.  
  290.     // [system directory drive]:\sig -> szSigDir
  291.  
  292.     GetSystemDirectory(szSystemDirectory, PATH_SIZE * sizeof(*szSystemDirectory));
  293.     szSigDir[0] = szSystemDirectory[0];
  294.     szSigDir[1] = TEXT('\0');
  295.     lstrcat(szSigDir, TEXT(":\\sig"));
  296.     lstrcpy(szFiles, szSigDir);
  297.     lstrcat(szFiles, TEXT("\\*"));
  298.  
  299.     hFindFile = FindFirstFile(szFiles, &FindFileData);
  300.  
  301.     if (hFindFile == INVALID_HANDLE_VALUE) {
  302.         return FALSE;
  303.     }
  304.  
  305.     // insert all the signature filenames into the table sigtable.
  306.     
  307.     do {
  308.         lstrcpy(szFileName, szSigDir);
  309.         lstrcat(szFileName, TEXT("\\"));
  310.         lstrcat(szFileName, FindFileData.cFileName);
  311.                 
  312.         TableInsert(sigtable, TEXT("NULL"), szFileName, 0);
  313.     } while (FindNextFile(hFindFile, &FindFileData) 
  314.                     || GetLastError() != ERROR_NO_MORE_FILES);
  315.  
  316.     FindClose(hFindFile);
  317. }    
  318.  
  319. /*************************************************************************************\
  320. * GetLBText()
  321. *
  322. * Gets the text of the currently selected (careted) item in the given
  323. *   listbox.
  324. *
  325. * Returns:  Index of selected item if successful, -1 on failure
  326. \*************************************************************************************/
  327.  
  328. LONG GetLBText(HWND hActiveLB, PTCHAR szItemBuff)
  329. {
  330.     LONG    lIndex;
  331.  
  332.     //
  333.     // Retrieve selected (careted) item.
  334.     //
  335.     lIndex = SendMessage( hActiveLB, LB_GETCARETINDEX,
  336.                           (WPARAM)NULL, (LPARAM)NULL );
  337.  
  338.     if( SendMessage( hActiveLB, LB_GETTEXT, (WPARAM)lIndex,
  339.                      (LPARAM)szItemBuff) == LB_ERR ){
  340.         ErrorMsg(TEXT("LBN_DBLCLK: Text retrieval failure."));
  341.         return(-1);
  342.     }
  343.  
  344.     return( lIndex );
  345. }
  346.  
  347. /*************************************************************************************\
  348. * UpdateFileLB()
  349. *
  350. * Updates the file listbox of the drive child given by sending an MM_FILLFILE
  351. *   message to it.
  352. *
  353. *  input:   hwnd    -   Handle of drive child to update file listbox of.
  354. \*************************************************************************************/
  355.  
  356. VOID UpdateFileLB(HWND hwnd)
  357. {
  358.     LPCINFO lpCInfo;
  359.  
  360.     lpCInfo = (LPCINFO)GetWindowLong(hwnd, GWL_USERDATA);
  361.  
  362.     SendMessage(hwnd, WM_COMMAND, (WPARAM)MM_FILLFILE, (LPARAM)0);
  363. }
  364.  
  365. /*************************************************************************************\
  366. * RunListBoxItem()
  367. *
  368. *  input:   lpCInfo   -   pointer to Drv child's LPCINFO structure
  369. *              cmd      -   integer specifying what action to perform on
  370. *                          the file corresponding to the selected 
  371. *                          file listbox text.
  372. *
  373. * purpose:
  374. * 1. Obtains the full pathname of the selected directory or file
  375. * in the file listbox.
  376. * 2. Depending on whether a directory or file has been selected and
  377. * depending on cmd, the appropriate action is taken:
  378. * - CFILEREncryptFile()
  379. * - EncryptDir()
  380. * - CFILERDecryptFile()
  381. * - DecryptDir()
  382. * - SignFile()
  383. * - VerifyFile()
  384. *
  385. * Returns TRUE if successful, FALSE if unsuccessful.
  386. * If a user tries to sign a directory, RunListBoxItem returns FALSE.            
  387. \*************************************************************************************/
  388.  
  389. BOOL RunListBoxItem(LPCINFO lpCInfo, int cmd)
  390. {
  391.     LONG        lIndex;
  392.     TCHAR        szBuf[PATH_SIZE];
  393.     TCHAR        szFileName[PATH_SIZE];
  394.     TCHAR        szBuf2[PATH_SIZE];
  395.     
  396.     if (!lpCInfo) {
  397.         ErrorMsg(TEXT("RunListBoxItem: lpCInfo is NULL."));
  398.         return FALSE;
  399.     }
  400.     
  401.     // get index of selected item in Directory listbox.
  402.     
  403.     lIndex = SendMessage( lpCInfo->hDirLB, LB_GETCARETINDEX,
  404.                           (WPARAM)NULL, (LPARAM)NULL );
  405.                           
  406.     // obtain full pathname of directory corresponding to selected text in
  407.     // directory listbox by accessing the string table for the directory listbox.
  408.     
  409.     if (!TableGetHidden(lpCInfo->DirTable, lIndex, szFileName)) {
  410.         ErrorMsg(TEXT("RunListBoxItem: TableGetHidden failed."));
  411.         return FALSE;
  412.     }
  413.    
  414.        // append a '\\' to the end of the full pathname if one isn't already there.
  415.        
  416.        if (szFileName[lstrlen(szFileName) - 1] != TEXT('\\')) {
  417.            if (!lstrcat(szFileName, TEXT("\\"))) {
  418.             ErrorMsg(TEXT("RunListBoxItem: lstrcat failed."));
  419.             return FALSE;
  420.         }
  421.       }  
  422.  
  423.     //
  424.     // Retrieve selected (careted) item.
  425.     //
  426.  
  427.     // get index of selected item in the file listbox.
  428.     
  429.     lIndex = GetLBText(lpCInfo->hFileLB, szBuf);
  430.  
  431.     if (lIndex == LB_ERR) {
  432.         ErrorMsg(TEXT("RunListBoxItem: GetLBText failed."));
  433.         return FALSE;
  434.     }
  435.     
  436.     // get the full pathname of the file corresponding to the selected text
  437.     // in the file listbox by accessing the string table for the 
  438.     // file listbox.
  439.         
  440.        if (!TableGetHidden(lpCInfo->FileTable, lIndex, szBuf)) {
  441.         ErrorMsg(TEXT("RunListBoxItem: TableGetHidden failed."));
  442.         return FALSE;
  443.     }
  444.     
  445.     if (WaitForSingleObject(ghDrvThread, INFINITE) == WAIT_FAILED) {
  446.         ErrorMsg(TEXT("RunListBoxItem: WaitForSingleObject failed."));
  447.         return FALSE;
  448.     }
  449.  
  450.     if (lpCInfo->hDirThread 
  451.         && WaitForSingleObject(lpCInfo->hDirThread, INFINITE) == WAIT_FAILED) {
  452.         ErrorMsg(TEXT("RunListBoxItem: WaitForSingleObject failed."));
  453.         return FALSE;
  454.     }
  455.     
  456.     lstrcpy(szBuf2, szBuf);
  457.     SimplifyFileName(szBuf2, szBuf);
  458.     lstrcat(szFileName, szBuf);
  459.     
  460.     // if szFileName is not encrypted and the user wants to encrypt/decrypt
  461.     if (!IsEncrypted(szFileName) && cmd == ENCRYPT_DECRYPT) {
  462.         // if szFileName is a directory
  463.         if (CFilerIsDirectory(szFileName)) {
  464.             // encrypt the directory
  465.             if (!EncryptDir(ghwndDrv, szFileName, lpCInfo)) {
  466.                 ErrorMsg(TEXT("RunListBoxItem: EncryptDir failed."));
  467.                 return FALSE;
  468.             }
  469.         }        
  470.         // not a directory
  471.         else {
  472.             // encrypt the file
  473.             if    (!CFILEREncryptFile(ghwndDrv, szFileName)) {
  474.                 ErrorMsg(TEXT("RunListBoxItem: CFILEREncryptFile failed."));
  475.                 return FALSE;
  476.             }
  477.         }
  478.         UpdateFileLB(ghwndDrv);
  479.     }
  480.     else if (cmd == ENCRYPT_DECRYPT) {
  481.         // if szFileName is a directory
  482.         if (CFilerIsDirectory(szFileName)) {
  483.             // decrypt the directory.
  484.             if (!DecryptDir(ghwndDrv, szFileName, lpCInfo)) {
  485.                 ErrorMsg(TEXT("RunListBoxItme: DecryptDir failed."));
  486.                 return FALSE;
  487.             }
  488.         }
  489.         else {        
  490.             // not a directory
  491.             if (!CFILERDecryptFile(ghwndDrv, szFileName)) {
  492.                  ErrorMsg(TEXT("RunListBoxItem: CFILERDecryptFile failed."));
  493.                  return FALSE;
  494.             }
  495.         }
  496.         UpdateFileLB(ghwndDrv);
  497.     }
  498.     else if (cmd == SIGN) {
  499.         // sign file if szFileName is not a directory
  500.         if (!CFilerIsDirectory(szFileName) && !SignFile(ghwndDrv, szFileName)) {
  501.              ErrorMsg(TEXT("RunListBoxItem: SignFile failed."));
  502.              return FALSE;
  503.         }
  504.         UpdateFileLB(ghwndDrv);
  505.     }
  506.     else if (cmd == VERIFY) {
  507.         // verify file is szFileName is not a directory.
  508.         if (!CFilerIsDirectory(szFileName) && !VerifyFile(ghwndDrv, szFileName)) {
  509.              ErrorMsg(TEXT("RunListBoxItem: VerifyFile failed."));
  510.              return FALSE;
  511.         }
  512.         UpdateFileLB(ghwndDrv);
  513.     }
  514.  
  515.     return TRUE;
  516. }
  517.  
  518. /*************************************************************************************\
  519. * CFilerIsDirectory()
  520. *
  521. * input - szDirName: In Parameter: Buffer containing full pathname of directory
  522. *
  523. * Purpose: returns TRUE if szDiretory is a directory or a hidden directory,
  524. * FALSE otherwise or if error. 
  525. \*************************************************************************************/
  526.  
  527. BOOL CFilerIsDirectory(LPTSTR szDirName) {
  528.     DWORD dwFileAttributes;
  529.  
  530.     if (!szDirName) {
  531.         ErrorMsg(TEXT("CFilerIsDirectory: szDirName is NULL."));
  532.         return FALSE;
  533.     }
  534.     
  535.     dwFileAttributes = GetFileAttributes(szDirName);
  536.  
  537.     if (dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
  538.         return TRUE;
  539.  
  540.     if (dwFileAttributes == (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN))
  541.         return TRUE;
  542.  
  543.     return FALSE;
  544. }
  545.  
  546. /*************************************************************************************\
  547. * SeparatePathName()
  548. *
  549. * First parameter (in parameter): szFileName - full path name to be separated
  550. *
  551. * Second parameter (out parameter): szDir - buffer to hold full pathname of directory
  552. *
  553. * Third parameter (out parameter): szFile - buffer to hold filename (not full pathname)
  554. *
  555. * Example: C:\directory\[foo] -> C:\directory + [foo]
  556. \*************************************************************************************/
  557.  
  558. BOOL SeparatePathName(LPTSTR szFileName, LPTSTR szDir, LPTSTR szFile) {
  559.     INT        i, j, nLen, nFileOffset;
  560.  
  561.     if (!szFileName) {
  562.         ErrorMsg(TEXT("SeparatePathName: szFileName is NULL."));
  563.         return FALSE;
  564.     }
  565.     
  566.     if (!szDir) {
  567.         ErrorMsg(TEXT("SeparatePathName: szDir is NULL."));
  568.         return FALSE;
  569.     }
  570.     
  571.     if (!szFile) {
  572.         ErrorMsg(TEXT("SeparatePathName: szFile is NULL."));
  573.         return FALSE;
  574.     }
  575.     
  576.     lstrcpy(szDir, TEXT("\0"));
  577.     lstrcpy(szFile, TEXT("\0"));
  578.     
  579.     nLen = lstrlen(szFileName);
  580.  
  581.     if (szFileName[nLen - 1] == TEXT('\\'))
  582.         for (i = nLen - 1; szFileName[i] != TEXT('\\') && i; i--);
  583.     else
  584.         for (i = nLen; szFileName[i] != TEXT('\\') && i; i--);
  585.     
  586.     nFileOffset = i + 1;
  587.     
  588.     for (i = 0; i < nFileOffset - 1; i++)
  589.         szDir[i] = szFileName[i];
  590.     szDir[i] = TEXT('\0');
  591.     
  592.     for (j = 0, i++; i < lstrlen(szFileName); i++, j++)
  593.         szFile[j] = szFileName[i];
  594.     szFile[j] = TEXT('\0');  
  595.     
  596.     return TRUE;
  597. }
  598.  
  599. /*************************************************************************************\
  600. * SeparatePathName2()
  601. *
  602. * First parameter (in parameter): szFileName - full path name to be separated
  603. *
  604. * Second parameter (out parameter): szDir - buffer to hold full pathname of directory
  605. *
  606. * Third parameter (out parameter): szFile - buffer to hold filename (not full pathname)
  607. *
  608. * brackets are stripped from the filename before the filename is inserted into szFile.
  609. *
  610. * C:\directory\[foo] -> C:\directory + foo
  611. \*************************************************************************************/
  612.  
  613. BOOL SeparatePathName2(LPTSTR szFileName, LPTSTR szDir, LPTSTR szFile) {
  614.     INT        i, j, nLen, nFileOffset;
  615.  
  616.     if (!szFileName) {
  617.         ErrorMsg(TEXT("SeparatePathName2: szFileName is NULL."));
  618.         return FALSE;
  619.     }
  620.     
  621.     if (!szDir) {
  622.         ErrorMsg(TEXT("SeparatePathName2: szDir is NULL."));
  623.         return FALSE;
  624.     }
  625.     
  626.     if (!szFile) {
  627.         ErrorMsg(TEXT("SeparatePathName2: szFile is NULL."));
  628.         return FALSE;
  629.     }
  630.     
  631.     lstrcpy(szDir, TEXT("\0"));
  632.     lstrcpy(szFile, TEXT("\0"));
  633.     
  634.     nLen = lstrlen(szFileName);
  635.  
  636.     if (szFileName[nLen - 1] == TEXT('\\'))
  637.         for (i = nLen - 1; szFileName[i] != TEXT('\\') && i; i--);
  638.     else
  639.         for (i = nLen; szFileName[i] != TEXT('\\') && i; i--);
  640.         
  641.     nFileOffset = i + 1;
  642.     
  643.     for (i = 0; i < nFileOffset - 1; i++)
  644.         szDir[i] = szFileName[i];
  645.     szDir[i] = TEXT('\0');
  646.     
  647.     for (j = 0, i++; i < lstrlen(szFileName); ) {
  648.         if (szFileName[i] == TEXT('[') || szFileName[i] == TEXT(']'))
  649.             i++;
  650.         else {
  651.             szFile[j] = szFileName[i];
  652.             i++;
  653.             j++;
  654.         }
  655.     }
  656.  
  657.     szFile[j] = TEXT('\0');  
  658.     
  659.     return TRUE;
  660. }
  661.  
  662. /*************************************************************************************\
  663. * IsEncrypted()
  664. * input:
  665. *
  666. * szFileName - In parameter: buffer containing filename
  667. *
  668. * If szFileName has a .CRP extension, IsEncrypted() returns TRUE, FALSE otherwise
  669. * or if failure.
  670. \*************************************************************************************/
  671.  
  672. BOOL IsEncrypted(LPTSTR szFileName) {
  673.     INT nLen;
  674.  
  675.     if (!szFileName) {
  676.         ErrorMsg(TEXT("IsEncrypted: szFileName is NULL."));
  677.         return FALSE;
  678.     }
  679.     
  680.     nLen = lstrlen(szFileName);
  681.  
  682.     if (szFileName[nLen - 4] == TEXT('.') &&
  683.           szFileName[nLen - 3] == TEXT('C') &&
  684.         szFileName[nLen - 2] == TEXT('R') &&
  685.         szFileName[nLen - 1] == TEXT('P'))
  686.         return TRUE;
  687.  
  688.     return FALSE;
  689. }
  690.  
  691. /*************************************************************************************\
  692. * IsLegalToAdd()
  693. *
  694. * input
  695. * in parameters
  696. * szFileName - buffer containing filename (not full pathname) of file in question
  697. *
  698. * purpose
  699. * determines whether szFileName is a file or directory that should be added to
  700. * the file listbox string table.
  701. *
  702. * returns
  703. * TRUE if szFileName is legal
  704. * FALSE otherwise
  705. \*************************************************************************************/
  706.  
  707. BOOL IsLegalToAdd(LPTSTR szFileName)
  708. {
  709.     if (lstrcmp(szFileName, TEXT(".."))
  710.      && lstrcmp(szFileName, TEXT("."))
  711.      && lstrcmp(szFileName, TEXT("dirinfo")))
  712.          return TRUE;
  713.     
  714.     return FALSE;
  715. }
  716.