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.

259 lines
5.9 KiB

  1. #ifndef _SMALLUTIL_H_
  2. #define _SMALLUTIL_H_
  3. // CCancellableThread
  4. //
  5. // Lets you define a thread object that can be cancelled by the creator.
  6. //To implement the thread, derivce from CCancellableThread and override the
  7. //run() function. run() will be ran in its own thread, and the value returned
  8. //by run can be accessed by GetResult(). run() should check IsCancelled()
  9. //at appropriate intervals and exit early if true.
  10. // Clients of the cancellable thread then create the object, and execute Run()
  11. //when ready. If they wish to cancel, they can call NotifyCancel().
  12. typedef class CCancellableThread
  13. {
  14. private:
  15. HANDLE _hCancelEvent;
  16. HANDLE _hThread;
  17. static DWORD WINAPI threadProc( LPVOID lpParameter);
  18. BOOL _fIsFinished;
  19. DWORD _dwThreadResult;
  20. public:
  21. CCancellableThread();
  22. ~CCancellableThread();
  23. virtual BOOL Initialize();
  24. BOOL IsCancelled();
  25. BOOL IsRunning();
  26. BOOL IsFinished();
  27. BOOL GetResult( PDWORD pdwResult);
  28. BOOL Run();
  29. BOOL NotifyCancel();
  30. BOOL WaitForNotRunning( DWORD dwMilliseconds, PBOOL pfFinished = NULL);
  31. BOOL WaitForCancel( DWORD dwMilliseconds, PBOOL pfCancelled = NULL);
  32. protected:
  33. virtual DWORD run() = 0;
  34. }*PCCancellableThread;
  35. // CQueueSortOf - a queue(sort of) used to store stuff
  36. //in a renumerable way..
  37. class CQueueSortOf
  38. {
  39. // This sort-of-queue is just a data structure to build up a list of items
  40. //(always adding to the end) and then be able to enumerate that list
  41. //repeatedly from start to end.
  42. // The list does not own any of the objects added to it..
  43. typedef struct SEntry
  44. {
  45. SEntry* pNext;
  46. void* data;
  47. } *PSEntry;
  48. PSEntry m_pHead, m_pTail;
  49. public:
  50. CQueueSortOf()
  51. {
  52. m_pHead = NULL;
  53. m_pTail = NULL;
  54. }
  55. ~CQueueSortOf()
  56. {
  57. while( m_pHead != NULL)
  58. {
  59. PSEntry temp = m_pHead;
  60. m_pHead = m_pHead->pNext;
  61. delete temp;
  62. }
  63. }
  64. bool InsertAtEnd( void* newElement)
  65. {
  66. PSEntry pNewEntry = new SEntry;
  67. if( pNewEntry == NULL)
  68. return false;
  69. pNewEntry->data = newElement;
  70. pNewEntry->pNext = NULL;
  71. if( m_pHead == NULL)
  72. {
  73. m_pHead = m_pTail = pNewEntry;
  74. }
  75. else
  76. {
  77. m_pTail->pNext = pNewEntry;
  78. m_pTail = pNewEntry;
  79. }
  80. return true;
  81. }
  82. // enumerations are managed by an 'iterator' which simply a void pointer into
  83. //the list. To start an enumeration, pass NULL as the iterator. The end
  84. //of enumeration will be indicated by a NULL iterator being returned.
  85. void* StepEnumerate( void* iterator)
  86. {
  87. return (iterator == NULL) ? m_pHead : ((PSEntry)iterator)->pNext;
  88. }
  89. void* Get( void* iterator)
  90. {
  91. return ((PSEntry)iterator)->data;
  92. }
  93. };
  94. // CGrowingString is a simple utility class that allows you to create
  95. //a string and append to it without worrying about reallocating memory
  96. //every time.
  97. class CGrowingString
  98. {
  99. public:
  100. WCHAR* m_szString;
  101. long m_iBufferSize;
  102. long m_iStringLength;
  103. CGrowingString()
  104. {
  105. m_szString = NULL;
  106. m_iBufferSize = 0;
  107. m_iStringLength = 0;
  108. }
  109. ~CGrowingString()
  110. {
  111. delete[] m_szString;
  112. }
  113. BOOL AppendToString( LPCWSTR pszNew)
  114. {
  115. long iLength = lstrlen( pszNew);
  116. if( m_szString == NULL
  117. || m_iStringLength + iLength + 1 > m_iBufferSize)
  118. {
  119. long iNewSize = max(1024, m_iStringLength + iLength * 10);
  120. WCHAR* pNewBuffer = new WCHAR[iNewSize];
  121. if( pNewBuffer == NULL)
  122. return FALSE;
  123. if( m_szString == NULL)
  124. {
  125. m_szString = pNewBuffer;
  126. m_iBufferSize = iNewSize;
  127. }
  128. else
  129. {
  130. StrCpyNW( pNewBuffer, m_szString, m_iStringLength + 1);
  131. delete[] m_szString;
  132. m_szString = pNewBuffer;
  133. m_iBufferSize = iNewSize;
  134. }
  135. }
  136. StrCpyNW( m_szString + m_iStringLength, pszNew, iLength+1);
  137. m_iStringLength += iLength;
  138. m_szString[m_iStringLength] = L'\0';
  139. return TRUE;
  140. }
  141. };
  142. //****************************************************
  143. //
  144. // FileOutputStream - retrofitted for WCHAR
  145. // from wininet\cookexp.cpp
  146. class CFileOutputStream
  147. {
  148. public:
  149. CFileOutputStream()
  150. {
  151. m_hFile = INVALID_HANDLE_VALUE;
  152. m_fError = FALSE;
  153. m_dwLastError = 0;
  154. }
  155. ~CFileOutputStream()
  156. {
  157. if( m_hFile != INVALID_HANDLE_VALUE)
  158. CloseHandle( m_hFile);
  159. }
  160. BOOL Load( LPCWSTR szFilename, BOOL fAppend)
  161. {
  162. m_hFile = CreateFile( szFilename, GENERIC_WRITE | GENERIC_READ, 0, NULL,
  163. fAppend ? OPEN_ALWAYS : CREATE_ALWAYS,
  164. FILE_ATTRIBUTE_NORMAL, NULL);
  165. if( m_hFile == INVALID_HANDLE_VALUE)
  166. {
  167. m_fError = TRUE;
  168. m_dwLastError = GetLastError();
  169. return FALSE;
  170. }
  171. if( fAppend
  172. && SetFilePointer( m_hFile, 0, NULL, FILE_END) == 0xFFFFFFFF)
  173. {
  174. m_fError = TRUE;
  175. m_dwLastError = GetLastError();
  176. return FALSE;
  177. }
  178. return TRUE;
  179. }
  180. BOOL DumpStr( const CHAR* szString, DWORD cLength)
  181. {
  182. DWORD dwTemp;
  183. if( m_fError == TRUE)
  184. return FALSE;
  185. if( WriteFile( m_hFile, szString, cLength, &dwTemp, NULL) == TRUE)
  186. {
  187. return TRUE;
  188. }
  189. else
  190. {
  191. m_fError = TRUE;
  192. m_dwLastError = GetLastError();
  193. return FALSE;
  194. }
  195. }
  196. BOOL WriteNewline()
  197. {
  198. static const LPCSTR szNewLine = "\r\n";
  199. return DumpStr( szNewLine, sizeof( szNewLine) - 1);
  200. }
  201. BOOL IsError()
  202. {
  203. return m_fError;
  204. }
  205. private:
  206. HANDLE m_hFile;
  207. BOOL m_fError;
  208. DWORD m_dwLastError;
  209. };
  210. #endif