source: trunk/Launcher/Launcher.cpp @ 71

Revision 71, 21.0 KB checked in by lowjoel, 7 years ago (diff)

Fixed the unable to find files error when erasing the recycle bin.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1// Launcher.cpp
2// $Id$
3//
4// Eraser. Secure data removal. For Windows.
5// Copyright © 1997-2001  Sami Tolvanen (sami@tolvanen.com).
6// Copyright © 2001-2006  Garrett Trant (support@heidi.ie).
7// Copyright © 2007 The Eraser Project.
8//
9// This program is free software; you can redistribute it and/or
10// modify it under the terms of the GNU General Public License
11// as published by the Free Software Foundation; either version 2
12// of the License, or (at your option) any later version.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22// 02111-1307, USA.
23
24#include "stdafx.h"
25#include "..\EraserDll\EraserDll.h"
26#include "..\EraserDll\FileLockResolver.h"
27#include "..\EraserUI\DriveCombo.h"
28#include "..\EraserUI\VisualStyles.h"
29#include "..\shared\FileHelper.h"
30#include "..\shared\UserInfo.h"
31#include "..\shared\Key.h"
32
33#include "Launcher.h"
34#include "ConfirmDialog.h"
35#include "LauncherDlg.h"
36
37#include <exception>
38#ifdef _DEBUG
39#define new DEBUG_NEW
40#undef THIS_FILE
41static char THIS_FILE[] = __FILE__;
42#endif
43
44/////////////////////////////////////////////////////////////////////////////
45// CLauncherApp
46
47BEGIN_MESSAGE_MAP(CLauncherApp, CWinApp)
48    //{{AFX_MSG_MAP(CLauncherApp)
49        // NOTE - the ClassWizard will add and remove mapping macros here.
50        //    DO NOT EDIT what you see in these blocks of generated code!
51    //}}AFX_MSG
52    ON_COMMAND(ID_HELP, CWinApp::OnHelp)
53END_MESSAGE_MAP()
54
55/////////////////////////////////////////////////////////////////////////////
56// CLauncherApp construction
57
58CLauncherApp::CLauncherApp() :
59m_pdlgEraser(0),
60m_hQueue(NULL)
61{
62    _set_se_translator(SeTranslator);
63}
64
65/////////////////////////////////////////////////////////////////////////////
66// The one and only CLauncherApp object
67
68CLauncherApp theApp;
69
70static BOOL ParseRecycledDirectory(LPCTSTR szDirectory, CStringArray& saFiles,
71                                   CStringArray& saDirectories, BOOL bNoINFO)
72{
73    static int      iRecursion = 0;
74
75    BOOL            bResult = FALSE;
76    HANDLE          hFind;
77    WIN32_FIND_DATA wfdData;
78
79    iRecursion++;
80
81    CString         strTemp;
82    CString         strDirectory(szDirectory);
83
84    // do not include the base directory
85    if (iRecursion > 1)
86        saDirectories.InsertAt(0, strDirectory);
87
88    if (!strDirectory.IsEmpty())
89    {
90        if (strDirectory[strDirectory.GetLength() - 1] != '\\')
91            strDirectory += "\\";
92
93        strTemp = strDirectory + "*";
94
95        hFind = FindFirstFile((LPCTSTR) strTemp, &wfdData);
96
97        if (hFind != INVALID_HANDLE_VALUE)
98        {
99            do
100            {
101                if (wfdData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
102                {
103                    // skip "." and ".."
104                    if (ISNT_SUBFOLDER(wfdData.cFileName))
105                        continue;
106
107                    strTemp = strDirectory + wfdData.cFileName;
108
109                    // recursive
110                    ParseRecycledDirectory((LPCTSTR) strTemp,
111                                           saFiles, saDirectories,
112                                           bNoINFO);
113                }
114                else
115                {
116                    if (_stricmp(wfdData.cFileName, "desktop.ini") == 0)
117                        continue;
118
119                    if (bNoINFO && _strnicmp(wfdData.cFileName, "INFO", 4) == 0)
120                        continue;
121
122                    strTemp = strDirectory + wfdData.cFileName;
123                    saFiles.Add(strTemp);
124                }
125            }
126            while (FindNextFile(hFind, &wfdData));
127
128            VERIFY(FindClose(hFind));
129
130            bResult = TRUE;
131        }
132    }
133
134    iRecursion--;
135    return bResult;
136}
137
138struct VersionHelper
139{
140    bool isVista;
141    VersionHelper()
142    {
143        isVista = false;
144
145        OSVERSIONINFOEX osvi;
146        BOOL bOsVersionInfoEx;
147
148        ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
149
150        // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
151        // If that fails, try using the OSVERSIONINFO structure.
152
153        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
154
155        if ( (bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi)) != TRUE )
156        {
157            osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
158            if ( !GetVersionEx ((OSVERSIONINFO *) &osvi) ) 
159                return ;
160        }
161        if ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId )
162        {
163            if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )
164            {
165
166                /*if( osvi.wProductType == VER_NT_WORKSTATION )
167                printf ("Windows Vista ");
168                else printf ("Windows Server \"Longhorn\" " );
169           
170            */
171                isVista = true;
172            }
173        }
174    }
175};
176static void LocateRecycledItems(CStringArray& saRecycled, CStringArray& saRecycledDirectories)
177{
178    CStringArray    straDrives;
179    CStringArray    lstraDrives;
180    TCHAR           szFS[MAX_PATH];
181    DWORD           dwFileSystem;
182    DWORD           dwAttributes;
183    int             iSize;
184    CString         strSID;
185    static VersionHelper version;
186
187    saRecycled.RemoveAll();
188    saRecycledDirectories.RemoveAll();
189
190    // find all hard drives installed to the system
191
192    GetLocalHardDrives(lstraDrives);
193
194    // determine user SID (works on NT only)
195
196    GetCurrentUserTextualSid(strSID);
197
198    // determine the location of the Recycle Bin (depending on the file system)
199
200    iSize = lstraDrives.GetSize();
201
202
203    while (iSize--)
204    {
205        if (GetVolumeInformation((LPCTSTR)lstraDrives[iSize], NULL, 0, NULL, NULL,
206            &dwFileSystem, szFS, MAX_PATH))
207        {
208            if (_stricmp(szFS, "NTFS") == 0)
209            {
210                straDrives.Add(lstraDrives[iSize]+ "RECYCLER\\NPROTECT");
211                if (!strSID.IsEmpty())
212                {
213                    //straDrives.SetAt(iSize, straDrives[iSize] + "RECYCLER\\" + strSID);
214                    straDrives.Add(lstraDrives[iSize] + "RECYCLER\\" + strSID);     
215                    straDrives.Add(lstraDrives[iSize] + "$Recycle.Bin\\" + strSID);
216                }
217                else
218                {
219                    //straDrives.SetAt(iSize, straDrives[iSize] + "RECYCLER");
220                    straDrives.Add(lstraDrives[iSize] + "RECYCLER");
221                    straDrives.Add(lstraDrives[iSize] + "$Recycle.Bin\\");
222                }
223            }
224            else
225                //straDrives.SetAt(iSize, straDrives[iSize] + "RECYCLED");
226                straDrives.Add(lstraDrives[iSize] + "RECYCLED");
227           
228        }
229    }
230
231   
232    // parse contents of the Recycle Bin folders except for the "desktop.ini"
233    // files
234
235    CString strTemp;
236    BOOL    bNoINFO = FALSE;
237    iSize = straDrives.GetSize();
238
239    HINSTANCE         hShell = AfxLoadLibrary(szShell32);
240    SHEMPTYRECYCLEBIN pSHEmptyRecycleBin = 0;
241
242    if (hShell)
243    {
244        pSHEmptyRecycleBin =
245            (SHEMPTYRECYCLEBIN)GetProcAddress(hShell, szSHEmptyRecycleBin);
246
247        bNoINFO = (pSHEmptyRecycleBin != NULL);
248
249        AfxFreeLibrary(hShell);
250    }
251
252    while (iSize--)
253    {
254        strTemp = straDrives[iSize];
255        dwAttributes = GetFileAttributes((LPCTSTR)straDrives[iSize]);
256
257        if (dwAttributes != (DWORD) -1 && (dwAttributes & FILE_ATTRIBUTE_SYSTEM))
258        {
259            ParseRecycledDirectory(strTemp,
260               saRecycled,
261               saRecycledDirectories,
262               bNoINFO);
263        }
264    }
265
266#if 0
267    CString strRecycled, strRecycledDirectories;
268    int i = 0;
269
270    for (i = 0, iSize = saRecycled.GetSize(); i < iSize; i++) {
271        strRecycled += saRecycled[i] + "\r\n";
272    }
273
274    for (i = 0, iSize = saRecycledDirectories.GetSize(); i < iSize; i++) {
275        strRecycledDirectories += saRecycledDirectories[i] + "\r\n";
276    }
277
278    AfxMessageBox(strSID);
279    AfxMessageBox(strRecycled);
280    AfxMessageBox(strRecycledDirectories);
281#endif
282}
283
284
285/////////////////////////////////////////////////////////////////////////////
286// CLauncherApp initialization
287BOOL CLauncherApp::InitInstance()
288{
289    // Standard initialization
290    // If you are not using these features and wish to reduce the size
291    // of your final executable, you should remove from the following
292    // the specific initialization routines you do not need.
293    eraserInit();
294
295    CString strCmdLine(m_lpCmdLine);
296    CString strCurrentParameter;
297
298    BOOL    bSilent             = FALSE;
299    BOOL    bResults            = -1;
300    BOOL    bResultsOnError     = -1;
301    BOOL    bOptions            = FALSE;
302    BOOL    bQueue              = FALSE;
303
304    CString strData;
305    CStringArray saFiles;
306    BOOL    bFiles              = FALSE;
307    BOOL    bFolders            = FALSE;
308    BOOL    bSubFolders         = FALSE;
309    BOOL    bKeepFolder         = FALSE;
310    BOOL    bDrive              = FALSE;
311    BOOL    bRecycled           = FALSE;
312    BOOL    bResolveLock        = FALSE;
313
314    ERASER_METHOD emMethod      = ERASER_METHOD_PSEUDORANDOM /*ERASER_METHOD_LIBRARY*/;
315    E_UINT16 uPasses            = 1;
316
317    // Declare an "Invalid command line" exception
318    class InvalidCommandLineException : public std::exception
319    {
320    public:
321        InvalidCommandLineException(const CString& msg)
322            : Message(msg)
323        {
324            chrBuf = NULL;
325        }
326
327        ~InvalidCommandLineException()
328        {
329            delete[] chrBuf;
330        }
331
332        virtual const char* what() const
333        {
334            if (!chrBuf)
335            {
336                CString msg = Message;
337                chrBuf = new char[msg.GetLength() + 1];
338                strcpy(chrBuf, msg.GetBuffer());
339                msg.ReleaseBuffer();
340            }
341            return chrBuf;
342        }
343
344    private:
345        mutable char* chrBuf;
346        CString Message;
347    };
348
349    try
350    {
351        if (!strCmdLine.IsEmpty())
352        {
353            while (GetNextParameter(strCmdLine, strCurrentParameter))
354            {
355                if (strCurrentParameter.CompareNoCase(szFile) == 0 &&
356                    strData.IsEmpty())
357                {
358                    // file
359                    if (!GetNextParameter(strCmdLine, strCurrentParameter))
360                        throw InvalidCommandLineException("-file was specified but no file name was given.");
361                    else
362                    {
363                        strData = strCurrentParameter;
364                        bFiles = TRUE;
365                    }
366                }
367                else if (strCurrentParameter.CompareNoCase(szResolveLock) == 0 &&
368                    strData.IsEmpty())
369                {
370                    // resolve locked files
371                    if (!GetNextParameter(strCmdLine, strCurrentParameter))
372                        throw InvalidCommandLineException("-rl was specified but no file name was given.");
373                    else
374                    {
375                        strData = strCurrentParameter;
376                        bResolveLock = TRUE;
377                    }
378                }
379                else if (strCurrentParameter.CompareNoCase(szFolder) == 0 &&
380                         strData.IsEmpty())
381                {
382                    // folder
383                    if (!GetNextParameter(strCmdLine, strCurrentParameter))
384                        throw InvalidCommandLineException("-folder was specified but no folder name was given.");
385                    else
386                    {
387                        strData = strCurrentParameter;
388                        bFiles = TRUE;
389                        bFolders = TRUE;
390
391                        if (strData[strData.GetLength() - 1] != '\\')
392                            strData += "\\";
393                    }
394                }
395                else if (strCurrentParameter.CompareNoCase(szDisk) == 0 &&
396                         strData.IsEmpty())
397                {
398                    // unused disk space
399                    if (!GetNextParameter(strCmdLine, strCurrentParameter))
400                        throw InvalidCommandLineException("-disk was specified but no file name was given.");
401                    else
402                    {
403                        bDrive = TRUE;
404
405                        if (strCurrentParameter != szDiskAll)
406                            strData.Format("%c:\\", strCurrentParameter[0]);
407                        else
408                            strData = strCurrentParameter;
409                    }
410                }
411                else if (strCurrentParameter.CompareNoCase(szRecycled) == 0)
412                {
413                    bRecycled   = TRUE;
414                    bFiles      = TRUE;
415                    bFolders    = FALSE;
416                }
417                else if (strCurrentParameter.CompareNoCase(szMethod) == 0)
418                {
419                    if (!GetNextParameter(strCmdLine, strCurrentParameter))
420                        throw InvalidCommandLineException("-method was specified but no method name was given.");
421                    else
422                    {
423                        if (strCurrentParameter.CompareNoCase(szMethodLibrary) == 0)
424                            emMethod = ERASER_METHOD_LIBRARY;
425                        else if (strCurrentParameter.CompareNoCase(szMethodGutmann) == 0)
426                            emMethod = ERASER_METHOD_GUTMANN;
427                        else if (strCurrentParameter.CompareNoCase(szMethodDoD) == 0)
428                            emMethod = ERASER_METHOD_DOD;
429                        else if (strCurrentParameter.CompareNoCase(szMethodDoD_E) == 0)
430                            emMethod = ERASER_METHOD_DOD_E;
431                        else if (strCurrentParameter.CompareNoCase(szMethodFL2K) == 0)
432                            emMethod = ERASER_METHOD_FIRST_LAST_2KB;
433                        else if (strCurrentParameter.CompareNoCase(szSchneier) == 0)
434                            emMethod = ERASER_METHOD_SCHNEIER;
435                        else if (strCurrentParameter.CompareNoCase(szMethodRandom) == 0)
436                        {
437                            emMethod = ERASER_METHOD_PSEUDORANDOM;
438
439                            if (!GetNextParameter(strCmdLine, strCurrentParameter))
440                                throw InvalidCommandLineException("-method Random was specified but no number of passes was specified.");
441                            else
442                            {
443                                char *sztmp = 0;
444                                E_UINT32 uCurrentParameter = strtoul((LPCTSTR)strCurrentParameter, &sztmp, 10);
445
446                                if (*sztmp != '\0' || uCurrentParameter > (E_UINT16)-1) {
447                                    throw InvalidCommandLineException("-method Random was specified an invalid number of passes was specified.");
448                                } else {
449                                    uPasses = (E_UINT16)uCurrentParameter;
450                                }
451                            }
452                        }
453                        else
454                            throw InvalidCommandLineException("Unrecognized method name '" + strCurrentParameter + "'");
455                    }
456                }
457                else if (strCurrentParameter.CompareNoCase(szSubFolders) == 0)
458                    bSubFolders = TRUE;
459                else if (strCurrentParameter.CompareNoCase(szKeepFolder) == 0)
460                    bKeepFolder = TRUE;
461                else if (strCurrentParameter.CompareNoCase(szSilent) == 0)
462                    bSilent = TRUE;
463                else if (strCurrentParameter.CompareNoCase(szResults) == 0)
464                    bResults = TRUE;
465                else if (strCurrentParameter.CompareNoCase(szResultsOnError) == 0)
466                {
467                    bResults = TRUE;
468                    bResultsOnError = TRUE;
469                }
470                else if (strCurrentParameter.CompareNoCase(szOptions) == 0)
471                    bOptions = TRUE;
472                else if (strCurrentParameter.CompareNoCase(szQueue) == 0)
473                    bQueue = TRUE;
474                else
475                    throw InvalidCommandLineException("Unrecognized parameter '" + strCurrentParameter + "'");
476            }
477        }
478        else
479        {
480            throw InvalidCommandLineException("Invalid command line.");
481        }
482
483        // conflicting command line parameters ?
484        if (((!bOptions && !bRecycled) && strData.IsEmpty()))
485            throw InvalidCommandLineException("No data to erase.");
486        if (!bFolders && bKeepFolder)
487            throw InvalidCommandLineException("Data to erase is not a folder, -keepfolder has no effect.");
488        if (bSilent && bResults)
489            throw InvalidCommandLineException("-silent and -results are mutually exclusive.");
490        if (bOptions && bQueue)
491            throw InvalidCommandLineException("The help command cannot be queued.");
492
493        // is the user naive enough to select the first/last 2KB pass with free space?
494        if (emMethod == ERASER_METHOD_FIRST_LAST_2KB && bDrive)
495        {
496            AfxMessageBox("The first/last 2KB erase cannot be used with Free Space erases.", MB_ICONERROR);
497            return FALSE;
498        }
499
500        //Now that the command line has been passed, check if we should display the
501        //results dialog (because it may not be overridde by the user)
502        CKey kReg;
503        if (kReg.Open(HKEY_CURRENT_USER, ERASER_REGISTRY_BASE))
504        {
505            if (bResults == -1)
506                kReg.GetValue(bResults, ERASER_REGISTRY_RESULTS_FILES, TRUE);
507            if (bResultsOnError == -1)
508                kReg.GetValue(bResultsOnError, ERASER_REGISTRY_RESULTS_WHENFAILED, FALSE);
509            kReg.Close();
510        }
511
512        m_pdlgEraser = new CLauncherDlg();
513        m_pMainWnd   = m_pdlgEraser;
514
515        if (!m_pdlgEraser->Create(IDD_LAUNCHER_DIALOG))
516        {
517            AfxMessageBox(IDS_ERROR_DIALOG, MB_ICONERROR, 0);
518            return FALSE;
519        }
520
521        if (bOptions)
522        {
523            m_pdlgEraser->Options();
524            return FALSE;
525        }
526        else
527        {
528            HandleQueue(bQueue);
529            if (bResolveLock)
530            {
531                try
532                {
533                    CFileLockResolver::Resolve(strData, saFiles);
534                }
535                catch (const std::exception& ee)
536                {
537                    AfxMessageBox(ee.what(), MB_ICONERROR);
538                    return FALSE;
539                }
540            }
541           
542            if (bFiles && !bFolders)
543            {
544                if (!bRecycled)
545                    findMatchingFiles(strData, saFiles, bSubFolders);
546                else
547                {
548                    LocateRecycledItems(saFiles, m_pdlgEraser->m_saFolders);
549
550                    if (saFiles.GetSize() > 0 && !bSilent)
551                    {
552                        CConfirmDialog cd(m_pdlgEraser);
553
554                        if (cd.DoModal() != IDOK)
555                            return FALSE;
556                    }
557                }
558            }
559            else
560            {
561                if (bDrive || GetFileAttributes((LPCTSTR)strData) != (DWORD)-1)
562                    saFiles.Add(strData);
563            }
564
565            if (saFiles.GetSize() > 0 || m_pdlgEraser->m_saFolders.GetSize() > 0)
566            {
567                if (!bSilent)
568                    m_pdlgEraser->ShowWindow(SW_SHOW);
569                else
570                    m_pdlgEraser->GetDlgItem(IDCANCEL)->EnableWindow(FALSE);
571
572                m_pdlgEraser->m_saFiles.Copy(saFiles);
573                m_pdlgEraser->m_bResults        = bResults;
574                m_pdlgEraser->m_bResultsOnError = bResultsOnError;
575                m_pdlgEraser->m_bUseFiles       = bFiles || bResolveLock;
576                m_pdlgEraser->m_bUseEmptySpace  = bDrive;
577                m_pdlgEraser->m_bFolders        = bFolders;
578                m_pdlgEraser->m_bSubFolders     = bSubFolders;
579                m_pdlgEraser->m_bKeepFolder     = bKeepFolder;
580                m_pdlgEraser->m_bRecycled       = bRecycled;
581                m_pdlgEraser->m_emMethod        = emMethod;
582                m_pdlgEraser->m_uPasses         = uPasses;
583
584                return m_pdlgEraser->Erase();
585            }
586            else if (!bSilent)
587            {
588                if (bRecycled)
589                    AfxMessageBox("Recycle Bin is empty.", MB_ICONERROR);
590                else
591                    AfxMessageBox("File not found. Nothing to erase. (" + strData + ")", MB_ICONERROR);
592            }
593        }
594    }
595    catch (InvalidCommandLineException& e)
596    {
597        CString msg;
598        msg.LoadString(AfxGetInstanceHandle(), IDS_CMDLINE_INCORRECT);
599        AfxMessageBox(CString(e.what()) + "\n\n" + msg, MB_ICONERROR);
600    }
601    catch (CException *e)
602    {
603        ASSERT(FALSE);
604        e->ReportError(MB_ICONERROR);
605        e->Delete();
606    }
607    catch (...)
608    {
609        ASSERT(FALSE);
610    }
611
612    return FALSE;
613}
614
615BOOL CLauncherApp::GetNextParameter(CString& strCmdLine, CString& strNextParameter) const
616{
617    strCmdLine.TrimRight();
618    strCmdLine.TrimLeft();
619
620    int iPos = strCmdLine.Find(' ');
621
622    if (iPos != -1)
623    {
624        strNextParameter = strCmdLine.Left(iPos);
625        strCmdLine = strCmdLine.Right(strCmdLine.GetLength() - iPos - 1);
626
627        if (!strNextParameter.IsEmpty() && strNextParameter[0] == '\"')
628        {
629            iPos = strCmdLine.Find('\"');
630
631            if (iPos != -1)
632            {
633                strNextParameter = strNextParameter.Right(strNextParameter.GetLength() - 1);
634                strNextParameter += " ";
635                strNextParameter += strCmdLine.Left(iPos);
636
637                strCmdLine = strCmdLine.Right(strCmdLine.GetLength() - iPos - 1);
638            }
639            else
640            {
641                strNextParameter = strNextParameter.Right(strNextParameter.GetLength() - 1);
642
643                iPos = strNextParameter.Find('\"');
644
645                if (iPos != -1)
646                    strNextParameter = strNextParameter.Left(iPos);
647            }
648        }
649
650        return (!strNextParameter.IsEmpty());
651    }
652    else if (!strCmdLine.IsEmpty())
653    {
654        strNextParameter = strCmdLine;
655        strCmdLine.Empty();
656
657        if (strNextParameter[0] == '\"')
658            strNextParameter = strNextParameter.Right(strNextParameter.GetLength() - 1);
659
660        if (strNextParameter[strNextParameter.GetLength() - 1] == '\"')
661            strNextParameter = strNextParameter.Left(strNextParameter.GetLength() - 1);
662
663        return TRUE;
664    }
665
666    return FALSE;
667}
668
669int CLauncherApp::ExitInstance()
670{
671    if (m_pdlgEraser)
672    {
673        m_pdlgEraser->DestroyWindow();
674
675        delete m_pdlgEraser;
676        m_pdlgEraser = 0;
677    }
678
679    if (m_hQueue != NULL)
680    {
681        ReleaseMutex(m_hQueue);
682        CloseHandle(m_hQueue);
683        m_hQueue = NULL;
684    }
685
686    // clean up the library
687    eraserEnd();
688
689    return CWinApp::ExitInstance();
690}
691
692void CLauncherApp::HandleQueue(BOOL bQueue)
693{
694    ASSERT(m_hQueue == NULL);
695
696    DWORD dwQueue = 0;
697    CString strName;
698
699    // find our position in the queue
700    for (DWORD dwNumber = 0; dwNumber < ERASERL_MAX_QUEUE; dwNumber++)
701    {
702        strName.Format(szQueueGUID, dwNumber);
703        m_hQueue = CreateMutex(NULL, TRUE, (LPCTSTR)strName);
704
705        if (m_hQueue == NULL)
706        {
707            // mutex creation failed!
708            return;
709        }
710        else if (GetLastError() == ERROR_ALREADY_EXISTS)
711        {
712            CloseHandle(m_hQueue);
713            m_hQueue = NULL;
714        }
715        else
716        {
717            // found our position in the queue!
718            dwQueue = dwNumber;
719            break;
720        }
721
722        if (dwNumber == ERASERL_MAX_QUEUE - 1)
723            AfxMessageBox(IDS_ERROR_MAX_INSTANCE, MB_ICONWARNING, 0);
724    }
725
726    // if we were ordered to wait until other instances have finished,
727    // why don't we then
728    if (m_hQueue != NULL && bQueue)
729    {
730        HANDLE m_hPrevInstance = NULL;
731        HANDLE m_hTemp = NULL;
732
733        while (dwQueue > 0)
734        {
735            strName.Format(szQueueGUID, --dwQueue);
736
737            m_hPrevInstance = OpenMutex(MUTEX_ALL_ACCESS, FALSE, (LPCTSTR)strName);
738
739            if (m_hPrevInstance != NULL)
740            {
741                WaitForSingleObject(m_hPrevInstance, INFINITE);
742
743                CloseHandle(m_hPrevInstance);
744                m_hPrevInstance = NULL;
745
746                m_hTemp = CreateMutex(NULL, TRUE, (LPCTSTR)strName);
747
748                if (m_hTemp == NULL)
749                    return;
750
751                ReleaseMutex(m_hQueue);
752                CloseHandle(m_hQueue);
753
754                m_hQueue = m_hTemp;
755                m_hTemp = NULL;
756            }
757        }
758    }
759}
Note: See TracBrowser for help on using the repository browser.