|
|
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.