Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
6.1 KiB

  1. #ifndef __2542cbc9_9348_4930_a641_c43c6497181b__
  2. #define __2542cbc9_9348_4930_a641_c43c6497181b__
  3. #include "gphelper.h"
  4. class CFoundFileMessageData
  5. {
  6. private:
  7. CSimpleString m_strFilename;
  8. private:
  9. CFoundFileMessageData(void);
  10. CFoundFileMessageData( const CFoundFileMessageData & );
  11. CFoundFileMessageData &operator=( const CFoundFileMessageData & );
  12. public:
  13. CFoundFileMessageData( const CSimpleString &strFilename )
  14. : m_strFilename(strFilename)
  15. {
  16. }
  17. ~CFoundFileMessageData(void)
  18. {
  19. }
  20. CSimpleString Name(void) const
  21. {
  22. return m_strFilename;
  23. }
  24. };
  25. class CFindFilesThread
  26. {
  27. private:
  28. CSimpleString m_strDirectory;
  29. CSimpleString m_strMask;
  30. HWND m_hwndNotify;
  31. UINT m_nNotifyMessage;
  32. HANDLE m_hEventCancel;
  33. int m_nDirectoryCount;
  34. int m_nFailedFileCount;
  35. int m_nSuccessfulFileCount;
  36. int m_nMaxFailedFiles;
  37. int m_nMaxSuccessfulFiles;
  38. int m_nMaxDirectories;
  39. CImageFileFormatVerifier m_ImageFileFormatVerifier;
  40. private:
  41. CFindFilesThread(
  42. const CSimpleString &strDirectory,
  43. const CSimpleString &strMask,
  44. HWND hwndNotify,
  45. UINT nNotifyMessage,
  46. HANDLE hEventCancel,
  47. int nMaxFailedFiles,
  48. int nMaxSuccessfulFiles,
  49. int nMaxDirectories
  50. )
  51. : m_strDirectory(strDirectory),
  52. m_strMask(strMask),
  53. m_hwndNotify(hwndNotify),
  54. m_nNotifyMessage(nNotifyMessage),
  55. m_hEventCancel(NULL),
  56. m_nDirectoryCount(0),
  57. m_nFailedFileCount(0),
  58. m_nSuccessfulFileCount(0),
  59. m_nMaxFailedFiles(nMaxFailedFiles),
  60. m_nMaxSuccessfulFiles(nMaxSuccessfulFiles),
  61. m_nMaxDirectories(nMaxDirectories)
  62. {
  63. if (!DuplicateHandle( GetCurrentProcess(), hEventCancel, GetCurrentProcess(), &m_hEventCancel, 0, FALSE, DUPLICATE_SAME_ACCESS ))
  64. m_hEventCancel = NULL;
  65. }
  66. ~CFindFilesThread(void)
  67. {
  68. if (m_hEventCancel)
  69. {
  70. CloseHandle(m_hEventCancel);
  71. m_hEventCancel = NULL;
  72. }
  73. }
  74. private:
  75. static bool FoundFile( bool bIsFile, LPCTSTR pszFilename, const WIN32_FIND_DATA *, PVOID pvParam )
  76. {
  77. CFindFilesThread *pThis = reinterpret_cast<CFindFilesThread*>(pvParam);
  78. if (pThis)
  79. return pThis->FoundFile( bIsFile, pszFilename );
  80. return false;
  81. }
  82. bool FoundFile( bool bIsFile, LPCTSTR pszFilename )
  83. {
  84. //WIA_PUSH_FUNCTION((TEXT("CFindFilesThread::FoundFile( %d, %s )"), bIsFile, pszFilename ));
  85. // Check to see if we've been cancelled
  86. if (m_hEventCancel)
  87. {
  88. DWORD dwRes = WaitForSingleObject(m_hEventCancel,0);
  89. if (WAIT_OBJECT_0 == dwRes)
  90. return false;
  91. }
  92. // If this is a file, and it is an image file that we can decode, package up a message and send it off
  93. if (bIsFile)
  94. {
  95. if (m_nNotifyMessage && m_hwndNotify && IsWindow(m_hwndNotify))
  96. {
  97. if (m_ImageFileFormatVerifier.IsImageFile(pszFilename))
  98. {
  99. m_nSuccessfulFileCount++;
  100. CFoundFileMessageData *pFoundFileMessageData = new CFoundFileMessageData( pszFilename );
  101. if (pFoundFileMessageData)
  102. {
  103. PostMessage( m_hwndNotify, m_nNotifyMessage, true, reinterpret_cast<LPARAM>(pFoundFileMessageData) );
  104. }
  105. }
  106. else m_nFailedFileCount++;
  107. }
  108. }
  109. else m_nDirectoryCount++;
  110. // If we've exceeded the number of failures we're allowed, stop searching
  111. if (m_nMaxFailedFiles && m_nFailedFileCount >= m_nMaxFailedFiles)
  112. {
  113. //WIA_TRACE((TEXT("FailedFileCount exceeded MaxFailedFiles, bailing out")));
  114. return false;
  115. }
  116. // If we've exceeded the number of files we want to handle, stop searching
  117. if (m_nMaxSuccessfulFiles && m_nSuccessfulFileCount >= m_nMaxSuccessfulFiles)
  118. {
  119. //WIA_TRACE((TEXT("m_nSuccessfulFileCount exceeded MaxSuccessfulFiles, bailing out")));
  120. return false;
  121. }
  122. // If we've exceeded the number of directories we're allowed, stop searching
  123. if (m_nMaxDirectories && m_nDirectoryCount >= m_nMaxDirectories)
  124. {
  125. //WIA_TRACE((TEXT("DirectoryCount exceeded MaxDirectories, bailing out")));
  126. return false;
  127. }
  128. return true;
  129. }
  130. bool Find(void)
  131. {
  132. bool bResult = RecursiveFindFiles( m_strDirectory, m_strMask, FoundFile, this );
  133. // Tell the window we're done
  134. if (m_nNotifyMessage && m_hwndNotify && IsWindow(m_hwndNotify))
  135. {
  136. PostMessage( m_hwndNotify, m_nNotifyMessage, FALSE, FALSE );
  137. }
  138. return bResult;
  139. }
  140. static DWORD __stdcall ThreadProc( PVOID pVoid )
  141. {
  142. CFindFilesThread *pFindFilesThread = reinterpret_cast<CFindFilesThread*>(pVoid);
  143. if (pFindFilesThread)
  144. {
  145. pFindFilesThread->Find();
  146. delete pFindFilesThread;
  147. }
  148. return 0;
  149. }
  150. public:
  151. static HANDLE Find(
  152. const CSimpleString &strDirectory,
  153. const CSimpleString &strMask,
  154. HWND hwndNotify,
  155. UINT nNotifyMessage,
  156. HANDLE hEventCancel,
  157. int nMaxFailedFiles,
  158. int nMaxSuccessfulFiles,
  159. int nMaxDirectories
  160. )
  161. {
  162. HANDLE hThread = NULL;
  163. CFindFilesThread *pFindFilesThread = new CFindFilesThread( strDirectory, strMask, hwndNotify, nNotifyMessage, hEventCancel, nMaxFailedFiles, nMaxSuccessfulFiles, nMaxDirectories );
  164. if (pFindFilesThread)
  165. {
  166. DWORD dwThreadId;
  167. hThread = CreateThread( NULL, 0, ThreadProc, pFindFilesThread, 0, &dwThreadId );
  168. if (!hThread)
  169. {
  170. delete pFindFilesThread;
  171. }
  172. else
  173. {
  174. SetThreadPriority( hThread, THREAD_PRIORITY_LOWEST );
  175. }
  176. }
  177. return hThread;
  178. }
  179. };
  180. #endif //__FINDTHRD_H_INCLUDED