|
|
1.1 ! root 1: ! 2: /******************************************************************************\ ! 3: * This is a part of the Microsoft Source Code Samples. ! 4: * Copyright (C) 1993 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: #include "porttool.h" ! 13: #include "port.h" ! 14: ! 15: ! 16: /* define line types returned from GetNextLine */ ! 17: #define VALID_LINE 0 ! 18: #define COMMENT_LINE 1 ! 19: #define EOF_LINE 2 ! 20: ! 21: #define CARRIAGE_RETURN 13 ! 22: #define LINE_FEED 10 ! 23: ! 24: /* define worker functions for this module */ ! 25: int WINAPI GetNextLine (char *, int, char *, char *, BOOL *); ! 26: int WINAPI NextLineLength (char *, char *, int); ! 27: BOOL WINAPI BkFilePortThread (LPBKPORTFILESTRUCT); ! 28: void WINAPI DateTimeStamp (char *); ! 29: ! 30: ! 31: ! 32: /* function creates a background porting thread */ ! 33: HANDLE WINAPI StartBkPortThread (LPBKPORTFILESTRUCT lpBkPort) ! 34: { ! 35: DWORD id; ! 36: ! 37: /* create thread with initial structure */ ! 38: return (lpBkPort->hThread = CreateThread ((LPSECURITY_ATTRIBUTES)NULL, ! 39: 4096, ! 40: (LPTHREAD_START_ROUTINE)BkFilePortThread, ! 41: (LPVOID)lpBkPort, ! 42: 0, ! 43: &id)); ! 44: } ! 45: ! 46: ! 47: /* independent thread function that performs background file porting */ ! 48: BOOL WINAPI BkFilePortThread ( ! 49: LPBKPORTFILESTRUCT lpBkPort) ! 50: { ! 51: HANDLE hEvents[nBKPORTEVENTS]; ! 52: HANDLE hFile; ! 53: OFSTRUCT of; ! 54: DWORD nFileSize; ! 55: DWORD nBytes; ! 56: HANDLE hFileBuffer; ! 57: char *lpFile, *lpFilePtr; ! 58: WORD wComplete, wIssues = 0; ! 59: int nLines = 0; ! 60: BOOL bCommentOn; ! 61: HANDLE hLine; ! 62: HANDLE hToken, hIssue, hSuggest, hHelp; ! 63: RESULT rIssue; ! 64: char *lpLine; ! 65: char szHeader[MAX_PATH], szToken[50], szIssue[50], szdt[50], ! 66: szSuggest[50], szHelp[50], szHelpFile[50], szEOL[50], szNL[5]; ! 67: ! 68: ! 69: /* adjust our priority to below normal */ ! 70: SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_BELOW_NORMAL); ! 71: ! 72: /* attach our thread input to the parent thread so we can post messages directly */ ! 73: AttachThreadInput (GetCurrentThreadId (), ! 74: GetWindowThreadProcessId (lpBkPort->hDlg, NULL), ! 75: TRUE); ! 76: ! 77: /* load file comment strings */ ! 78: LoadString (GetModuleHandle (NULL), IDS_BKPORTNEWLINE, szNL, 5); ! 79: LoadString (GetModuleHandle (NULL), IDS_BKPORTHEADER, szHeader, MAX_PATH); ! 80: LoadString (GetModuleHandle (NULL), IDS_BKPORTTOKEN, szToken, 50); ! 81: LoadString (GetModuleHandle (NULL), IDS_BKPORTISSUE, szIssue, 50); ! 82: LoadString (GetModuleHandle (NULL), IDS_BKPORTSUGGEST, szSuggest, 50); ! 83: LoadString (GetModuleHandle (NULL), IDS_BKPORTHELP, szHelp, 50); ! 84: LoadString (GetModuleHandle (NULL), IDS_BKPORTHELPFILE, szHelpFile, 50); ! 85: LoadString (GetModuleHandle (NULL), IDS_BKPORTEOL, szEOL, 50); ! 86: ! 87: /* initialize wait events for communication between threads */ ! 88: if (!CreateEvents (hEvents, lpBkPort)) ! 89: return FALSE; ! 90: ! 91: /* open file for porting and read into buffer */ ! 92: if ((int)(hFile = (HANDLE)OpenFile (lpBkPort->szFilePath, &of, OF_READWRITE)) == -1) ! 93: { ! 94: DestroyEvents (hEvents); ! 95: return FALSE; ! 96: } ! 97: ! 98: /* global allocate buffer for file */ ! 99: if (!(hFileBuffer = GlobalAlloc (GPTR, (nFileSize = GetFileSize (hFile, NULL))+1)) || ! 100: !(lpFile = (char *)GlobalLock (hFileBuffer))) ! 101: { ! 102: CloseHandle (hFile); ! 103: DestroyEvents (hEvents); ! 104: return FALSE; ! 105: } ! 106: ! 107: /* allocate initial line buffer of reasonable size */ ! 108: hLine = GlobalAlloc (GMEM_MOVEABLE, 1024); ! 109: ! 110: /* allocate local memory segments for porttool RESULT strings */ ! 111: if (!(rIssue.lpszToken = LocalLock (hToken = LocalAlloc (LHND, MAXTOKENLEN))) || ! 112: !(rIssue.lpszHelpStr = LocalLock (hHelp = LocalAlloc (LHND, MAXHELPLEN))) || ! 113: !(rIssue.lpszIssue = LocalLock (hIssue = LocalAlloc (LHND, MAXISSUELEN))) || ! 114: !(rIssue.lpszSuggest = LocalLock (hSuggest = LocalAlloc (LHND, MAXSUGGESTLEN)))) ! 115: { ! 116: CloseHandle (hFile); ! 117: GlobalUnlock (lpFile); ! 118: GlobalFree (hFileBuffer); ! 119: DestroyEvents (hEvents); ! 120: GlobalFree (hLine); ! 121: return FALSE; ! 122: } ! 123: ! 124: /* read entire file into buffer and zero terminate */ ! 125: ReadFile (hFile, lpFile, nFileSize, &nBytes, NULL); ! 126: lpFile[nFileSize] = 0; ! 127: lpFilePtr = lpFile; ! 128: ! 129: /* if bytes read not equal to size of file, abort */ ! 130: if (nBytes != nFileSize) ! 131: { ! 132: CloseHandle (hFile); ! 133: GlobalUnlock (lpFile); ! 134: GlobalFree (hFileBuffer); ! 135: DestroyEvents (hEvents); ! 136: GlobalFree (hLine); ! 137: return FALSE; ! 138: } ! 139: ! 140: /* reset file to size zero before beginning porting */ ! 141: SetFilePointer (hFile, 0, NULL, FILE_BEGIN); ! 142: SetEndOfFile (hFile); ! 143: WriteFile (hFile, szHeader, strlen (szHeader), &nBytes, NULL); ! 144: WriteFile (hFile, lpBkPort->szFile, strlen (lpBkPort->szFile), &nBytes, NULL); ! 145: WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL); ! 146: WriteFile (hFile, szNL, strlen (szNL), &nBytes, NULL); ! 147: ! 148: while (TRUE) ! 149: { ! 150: /* wait 1ms for either abort or status events to signal */ ! 151: switch (WaitForMultipleObjects (nBKPORTEVENTS, hEvents, FALSE, 1)) ! 152: { ! 153: case BKPORT_ABORT: ! 154: { ! 155: char szAbort[MAX_PATH]; ! 156: ! 157: /* create time and date */ ! 158: DateTimeStamp (szdt); ! 159: ! 160: /* write header line */ ! 161: WriteFile (hFile, szHeader, strlen (szHeader), &nBytes, NULL); ! 162: WriteFile (hFile, szdt, strlen (szdt), &nBytes, NULL); ! 163: WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL); ! 164: WriteFile (hFile, szNL, strlen (szNL), &nBytes, NULL); ! 165: ! 166: /* load abort string and write to file */ ! 167: LoadString (GetModuleHandle (NULL), ! 168: IDS_BKPORTABORT, ! 169: szAbort, ! 170: MAX_PATH); ! 171: WriteFile (hFile, szAbort, strlen (szAbort), (LPDWORD)&nBytes, NULL); ! 172: ! 173: /* write rest of file to disk */ ! 174: WriteFile (hFile, ! 175: (VOID *)lpFilePtr, ! 176: (nFileSize - (lpFilePtr-lpFile)), ! 177: (LPDWORD)&nBytes, ! 178: NULL); ! 179: ! 180: /* clean up */ ! 181: CloseHandle (hFile); ! 182: GlobalUnlock (lpFile); ! 183: GlobalFree (hFileBuffer); ! 184: GlobalFree (hLine); ! 185: DestroyEvents (hEvents); ! 186: ! 187: /* free RESULT strings */ ! 188: LocalUnlock (hToken); LocalFree (hToken); ! 189: LocalUnlock (hHelp); LocalFree (hHelp); ! 190: LocalUnlock (hIssue); LocalFree (hIssue); ! 191: LocalUnlock (hSuggest); LocalFree (hSuggest); ! 192: ! 193: /* exit thread */ ! 194: return FALSE; ! 195: } ! 196: break; ! 197: ! 198: case BKPORT_STATUS: ! 199: /* post message to parent thread with status info */ ! 200: PostMessage (lpBkPort->hDlg, ! 201: UM_STATUSUPDATE, ! 202: MAKELONG (wIssues, wComplete), ! 203: nLines); ! 204: break; ! 205: ! 206: case WAIT_TIMEOUT: ! 207: /* if we timed out ignore */ ! 208: break; ! 209: ! 210: default: ! 211: /* anything else is an error */ ! 212: ErrorNotify (lpBkPort->hDlg, GetLastError ()); ! 213: goto DONE; ! 214: break; ! 215: } ! 216: ! 217: /* reset line buffer */ ! 218: GlobalReAlloc (hLine, ! 219: NextLineLength (lpFilePtr, lpFile, nFileSize), ! 220: GMEM_MOVEABLE); ! 221: lpLine = (char *)GlobalLock (hLine); ! 222: *lpLine = 0; ! 223: ! 224: /* get next line from file buffer */ ! 225: switch (GetNextLine (lpFile, nFileSize, lpFilePtr, lpLine, &bCommentOn)) ! 226: { ! 227: /* check valid strings for porting issues */ ! 228: case VALID_LINE: ! 229: /* initialize rIssue string lengths */ ! 230: *(WORD *)rIssue.lpszToken = MAXTOKENLEN; ! 231: *(WORD *)rIssue.lpszHelpStr = MAXHELPLEN; ! 232: *(WORD *)rIssue.lpszIssue = MAXISSUELEN; ! 233: *(WORD *)rIssue.lpszSuggest = MAXSUGGESTLEN; ! 234: ! 235: if (CheckString (lpLine, lpBkPort->dwPTFlags, &rIssue)) ! 236: { ! 237: /* create time and date */ ! 238: DateTimeStamp (szdt); ! 239: ! 240: /* write header line */ ! 241: WriteFile (hFile, szNL, strlen (szNL), &nBytes, NULL); ! 242: WriteFile (hFile, szHeader, strlen (szHeader), &nBytes, NULL); ! 243: WriteFile (hFile, szdt, strlen (szdt), &nBytes, NULL); ! 244: WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL); ! 245: ! 246: /* write token line */ ! 247: WriteFile (hFile, szToken, strlen (szToken), &nBytes, NULL); ! 248: WriteFile (hFile, ! 249: rIssue.lpszToken, ! 250: strlen (rIssue.lpszToken), ! 251: &nBytes, ! 252: NULL); ! 253: WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL); ! 254: ! 255: /* write issue line */ ! 256: WriteFile (hFile, szIssue, strlen (szIssue), &nBytes, NULL); ! 257: WriteFile (hFile, ! 258: rIssue.lpszIssue, ! 259: strlen (rIssue.lpszIssue), ! 260: &nBytes, ! 261: NULL); ! 262: WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL); ! 263: ! 264: /* if suggestion */ ! 265: if (*(rIssue.lpszSuggest)) ! 266: { ! 267: WriteFile (hFile, szSuggest, strlen (szSuggest), &nBytes, NULL); ! 268: WriteFile (hFile, ! 269: rIssue.lpszSuggest, ! 270: strlen (rIssue.lpszSuggest), ! 271: &nBytes, ! 272: NULL); ! 273: WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL); ! 274: } ! 275: ! 276: /* if help string */ ! 277: if (*(rIssue.lpszSuggest)) ! 278: { ! 279: WriteFile (hFile, szHelp, strlen (szHelp), &nBytes, NULL); ! 280: WriteFile (hFile, ! 281: rIssue.lpszHelpStr, ! 282: strlen (rIssue.lpszHelpStr), ! 283: &nBytes, ! 284: NULL); ! 285: WriteFile (hFile, szHelpFile, strlen (szHelpFile), &nBytes, NULL); ! 286: WriteFile (hFile, szEOL, strlen (szEOL), &nBytes, NULL); ! 287: } ! 288: ! 289: wIssues++; ! 290: } ! 291: ! 292: case COMMENT_LINE: ! 293: /* write line to file whether comment or not */ ! 294: WriteFile (hFile, lpLine, strlen (lpLine), &nBytes, NULL); ! 295: break; ! 296: ! 297: case EOF_LINE: ! 298: if (*lpLine) ! 299: WriteFile (hFile, lpLine, strlen (lpLine), &nBytes, NULL); ! 300: goto DONE; ! 301: break; ! 302: } ! 303: ! 304: /* unlock line buffer */ ! 305: GlobalUnlock (hLine); ! 306: ! 307: /* update status counts */ ! 308: lpFilePtr += strlen (lpLine); ! 309: nLines++; ! 310: wComplete = (WORD)(((lpFilePtr-lpFile)*100)/nFileSize); ! 311: } ! 312: ! 313: DONE: ! 314: /* clean up */ ! 315: CloseHandle (hFile); ! 316: GlobalUnlock (lpFile); ! 317: GlobalFree (hFileBuffer); ! 318: GlobalFree (hLine); ! 319: DestroyEvents (hEvents); ! 320: ! 321: /* free RESULT strings */ ! 322: LocalUnlock (hToken); LocalFree (hToken); ! 323: LocalUnlock (hHelp); LocalFree (hHelp); ! 324: LocalUnlock (hIssue); LocalFree (hIssue); ! 325: LocalUnlock (hSuggest); LocalFree (hSuggest); ! 326: ! 327: /* send message to parent that thread is dead */ ! 328: PostMessage (lpBkPort->hDlg, ! 329: UM_THREADCOMPLETE, ! 330: (WPARAM)lpBkPort->hThread, ! 331: 0); ! 332: ! 333: /* exit thread */ ! 334: return TRUE; ! 335: } ! 336: ! 337: ! 338: ! 339: void WINAPI DateTimeStamp ( ! 340: char *lpszDT) ! 341: { ! 342: SYSTEMTIME dt; ! 343: char Buff[10]; ! 344: ! 345: /* create time and date stamp */ ! 346: GetSystemTime (&dt); ! 347: strcpy (lpszDT, itoa (dt.wMonth, Buff, 10)); ! 348: strcat (lpszDT, "/"); ! 349: strcat (lpszDT, itoa (dt.wDay, Buff, 10)); ! 350: strcat (lpszDT, "/"); ! 351: strcat (lpszDT, itoa (dt.wYear, Buff, 10)); ! 352: strcat (lpszDT, " "); ! 353: strcat (lpszDT, itoa (dt.wHour, Buff, 10)); ! 354: strcat (lpszDT, ":"); ! 355: strcat (lpszDT, itoa (dt.wMinute, Buff, 10)); ! 356: } ! 357: ! 358: ! 359: ! 360: ! 361: ! 362: BOOL WINAPI CreateEvents ( ! 363: HANDLE *lphEvents, ! 364: LPBKPORTFILESTRUCT lpBkPort) ! 365: { ! 366: char szEvent[MAX_PATH]; ! 367: ! 368: ! 369: LoadString (GetModuleHandle (NULL), IDS_BKPORTABORT, szEvent, MAX_PATH); ! 370: strcat (szEvent, lpBkPort->szFile); ! 371: if (!(lphEvents[BKPORT_ABORT] = CreateEvent (NULL, TRUE, FALSE, szEvent))) ! 372: return FALSE; ! 373: ! 374: LoadString (GetModuleHandle (NULL), IDS_BKPORTSTATUS, szEvent, MAX_PATH); ! 375: strcat (szEvent, lpBkPort->szFile); ! 376: if (!(lphEvents[BKPORT_STATUS] = CreateEvent (NULL, TRUE, FALSE, szEvent))) ! 377: { ! 378: CloseHandle (lphEvents[BKPORT_ABORT]); ! 379: return FALSE; ! 380: } ! 381: ! 382: /* return success */ ! 383: return TRUE; ! 384: } ! 385: ! 386: ! 387: ! 388: ! 389: void WINAPI DestroyEvents ( ! 390: HANDLE *lphEvents) ! 391: { ! 392: /* close event handles */ ! 393: CloseHandle (lphEvents[BKPORT_ABORT]); ! 394: CloseHandle (lphEvents[BKPORT_STATUS]); ! 395: } ! 396: ! 397: ! 398: ! 399: ! 400: int WINAPI NextLineLength ( ! 401: char *lpFilePtr, ! 402: char *lpFile, ! 403: int nFileSize) ! 404: { ! 405: int nCnt=0; ! 406: char *lpf = lpFilePtr; ! 407: ! 408: /* count all characters up to end of file or CR/LF sequence */ ! 409: while (lpf && ! 410: lpf-lpFile < nFileSize && ! 411: *lpf != CARRIAGE_RETURN && ! 412: *(lpf+1) != LINE_FEED) ! 413: { ! 414: lpf++; ! 415: nCnt++; ! 416: } ! 417: ! 418: /* length plus 3 for CR/LF/0 terminator sequence */ ! 419: return nCnt + 3; ! 420: } ! 421: ! 422: ! 423: ! 424: ! 425: int WINAPI GetNextLine ( ! 426: char *lpFile, ! 427: int nFileSize, ! 428: char *lpFilePtr, ! 429: char *lpLine, ! 430: BOOL *bCommentOn) ! 431: { ! 432: char *lpf = lpFilePtr; ! 433: char *lpl = lpLine; ! 434: ! 435: /* copy all characters up to end of file or CR/LF sequence */ ! 436: while (lpf && ! 437: lpf-lpFile < nFileSize && ! 438: *lpf != CARRIAGE_RETURN && ! 439: *(lpf+1) != LINE_FEED) ! 440: *lpl++ = *lpf++; ! 441: ! 442: /* check for end of buffer */ ! 443: if (lpf-lpFile >= nFileSize) ! 444: return EOF_LINE; ! 445: ! 446: /* copy carriage return and line feed to line and terminate */ ! 447: *lpl++ = *lpf++; ! 448: *lpl++ = *lpf++; ! 449: *lpl = 0; ! 450: ! 451: /* increment lpl to first non space character in line */ ! 452: lpl = lpLine; ! 453: while (*lpl == ' ') ! 454: lpl++; ! 455: ! 456: /* see if single line comments exist */ ! 457: if (*lpl == '/' && ! 458: *(lpl+1) == '/') ! 459: return COMMENT_LINE; ! 460: ! 461: /* see if comments begin */ ! 462: if (*lpl == '/' && ! 463: *(lpl+1) == '*') ! 464: *bCommentOn = TRUE; ! 465: ! 466: /* if comment on, see if it terminates yet */ ! 467: if (*bCommentOn) ! 468: { ! 469: lpl = lpLine; ! 470: while (*lpl) ! 471: { ! 472: if (*lpl == '*' && ! 473: *(lpl+1) == '/') ! 474: { ! 475: *bCommentOn = FALSE; ! 476: break; ! 477: } ! 478: lpl++; ! 479: } ! 480: ! 481: /* if more text on line, valid line */ ! 482: while (*lpl) ! 483: if (*lpl != '*' && ! 484: *(lpl+1) != '/') ! 485: return VALID_LINE; ! 486: else ! 487: return COMMENT_LINE; ! 488: } ! 489: ! 490: /* if haven't returned yet, must be valid line */ ! 491: return VALID_LINE; ! 492: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.