Release 961215
[wine/multimedia.git] / programs / progman / grpfile.c
blob5e8b5b2cdb524102f9c3176a95c91ad2a146ed5f
1 /*
2 * Program Manager
4 * Copyright 1996 Ulrich Schmid
5 */
7 #include <windows.h>
8 #include "progman.h"
10 #define MALLOCHUNK 1000
12 #define GET_USHORT(buffer, i)\
13 (((BYTE)((buffer)[(i)]) + 0x100 * (BYTE)((buffer)[(i)+1])))
14 #define GET_SHORT(buffer, i)\
15 (((BYTE)((buffer)[(i)]) + 0x100 * (signed char)((buffer)[(i)+1])))
16 #define PUT_SHORT(buffer, i, s)\
17 (((buffer)[(i)] = (s) & 0xff, (buffer)[(i)+1] = ((s) >> 8) & 0xff))
19 static BOOL GRPFILE_ReadFileToBuffer(LPCSTR, HLOCAL*, INT*);
20 static HLOCAL GRPFILE_ScanGroup(LPCSTR, INT, LPCSTR, BOOL);
21 static HLOCAL GRPFILE_ScanProgram(LPCSTR, INT, LPCSTR, INT,
22 LPCSTR, HLOCAL,LPCSTR);
23 static BOOL GRPFILE_DoWriteGroupFile(HFILE file, GROUP *group);
25 /***********************************************************************
27 * GRPFILE_ModifyFileName
29 * Change extension `.grp' to `.gr'
32 static VOID GRPFILE_ModifyFileName(LPSTR lpszNewName, LPCSTR lpszOrigName,
33 INT nSize, BOOL bModify)
35 lstrcpyn(lpszNewName, lpszOrigName, nSize);
36 lpszNewName[nSize-1] = '\0';
37 if (!bModify) return;
38 if (!lstrcmpi(lpszNewName + strlen(lpszNewName) - 4, ".grp"))
39 lpszNewName[strlen(lpszNewName) - 1] = '\0';
42 /***********************************************************************
44 * GRPFILE_ReadGroupFile
47 HLOCAL GRPFILE_ReadGroupFile(LPCSTR lpszPath)
49 CHAR szPath_gr[MAX_PATHNAME_LEN];
50 BOOL bFileNameModified = FALSE;
51 OFSTRUCT dummy;
52 HLOCAL hBuffer, hGroup;
53 INT size;
55 /* if `.gr' file exists use that */
56 GRPFILE_ModifyFileName(szPath_gr, lpszPath, MAX_PATHNAME_LEN, TRUE);
57 if (OpenFile(szPath_gr, &dummy, OF_EXIST) != HFILE_ERROR)
59 lpszPath = szPath_gr;
60 bFileNameModified = TRUE;
63 /* Read the whole file into a buffer */
64 if (!GRPFILE_ReadFileToBuffer(lpszPath, &hBuffer, &size))
66 MAIN_MessageBoxIDS_s(IDS_GRPFILE_READ_ERROR_s, lpszPath, IDS_ERROR, MB_YESNO);
67 return(0);
70 /* Interpret buffer */
71 hGroup = GRPFILE_ScanGroup(LocalLock(hBuffer), size,
72 lpszPath, bFileNameModified);
73 if (!hGroup)
74 MAIN_MessageBoxIDS_s(IDS_GRPFILE_READ_ERROR_s, lpszPath, IDS_ERROR, MB_YESNO);
76 LocalFree(hBuffer);
78 return(hGroup);
81 /***********************************************************************
83 * GRPFILE_ReadFileToBuffer
86 static BOOL GRPFILE_ReadFileToBuffer(LPCSTR path, HLOCAL *phBuffer,
87 INT *piSize)
89 INT len, size;
90 LPSTR buffer;
91 HLOCAL hBuffer, hNewBuffer;
92 HFILE file;
94 file=_lopen(path, OF_READ);
95 if (file == HFILE_ERROR) return FALSE;
97 size = 0;
98 hBuffer = LocalAlloc(LMEM_FIXED, size + MALLOCHUNK + 1);
99 if (!hBuffer) return FALSE;
100 buffer = LocalLock(hBuffer);
102 while ((len = _lread(file, buffer + size, MALLOCHUNK))
103 == MALLOCHUNK)
105 size += len;
106 hNewBuffer = LocalReAlloc(hBuffer, size + MALLOCHUNK + 1,
107 LMEM_FIXED);
108 if (!hNewBuffer)
110 LocalFree(hBuffer);
111 return FALSE;
113 hBuffer = hNewBuffer;
114 buffer = LocalLock(hBuffer);
117 _lclose(file);
119 if (len == HFILE_ERROR)
121 LocalFree(hBuffer);
122 return FALSE;
125 size += len;
126 buffer[size] = 0;
128 *phBuffer = hBuffer;
129 *piSize = size;
130 return TRUE;
133 /***********************************************************************
134 * GRPFILE_ScanGroup
137 static HLOCAL GRPFILE_ScanGroup(LPCSTR buffer, INT size,
138 LPCSTR lpszGrpFile,
139 BOOL bModifiedFileName)
141 HLOCAL hGroup;
142 INT i, seqnum;
143 LPCSTR extension;
144 LPCSTR lpszName;
145 INT x, y, width, height, iconx, icony, nCmdShow;
146 INT number_of_programs;
147 BOOL bOverwriteFileOk;
149 if (buffer[0] != 'P' || buffer[1] != 'M') return(0);
150 if (buffer[2] == 'C' && buffer[3] == 'C')
151 /* original with checksum */
152 bOverwriteFileOk = FALSE;
153 else if (buffer[2] == 'X' && buffer[3] == 'X')
154 /* modified without checksum */
155 bOverwriteFileOk = TRUE;
156 else return(0);
158 /* checksum = GET_USHORT(buffer, 4) (ignored) */
160 extension = buffer + GET_USHORT(buffer, 6);
161 if (extension == buffer + size) extension = 0;
162 else if (extension + 6 > buffer + size) return(0);
164 nCmdShow = GET_USHORT(buffer, 8);
165 x = GET_SHORT(buffer, 10);
166 y = GET_SHORT(buffer, 12);
167 width = GET_USHORT(buffer, 14);
168 height = GET_USHORT(buffer, 16);
169 iconx = GET_SHORT(buffer, 18);
170 icony = GET_SHORT(buffer, 20);
171 lpszName = buffer + GET_USHORT(buffer, 22);
172 if (lpszName >= buffer + size) return(0);
174 /* unknown bytes 24 - 31 ignored */
176 Unknown bytes should be:
177 wLogPixelsX = GET_SHORT(buffer, 24);
178 wLogPixelsY = GET_SHORT(buffer, 26);
179 byBitsPerPixel = byte at 28;
180 byPlanes = byte at 29;
181 wReserved = GET_SHORT(buffer, 30);
184 hGroup = GROUP_AddGroup(lpszName, lpszGrpFile, nCmdShow, x, y,
185 width, height, iconx, icony,
186 bModifiedFileName, bOverwriteFileOk,
187 TRUE);
188 if (!hGroup) return(0);
190 number_of_programs = GET_USHORT(buffer, 32);
191 if (2 * number_of_programs + 34 > size) return(0);
192 for (i=0, seqnum=0; i < number_of_programs; i++, seqnum++)
194 LPCSTR program_ptr = buffer + GET_USHORT(buffer, 34 + 2*i);
195 if (program_ptr + 24 > buffer + size) return(0);
196 if (!GET_USHORT(buffer, 34 + 2*i)) continue;
197 if (!GRPFILE_ScanProgram(buffer, size, program_ptr, seqnum,
198 extension, hGroup, lpszGrpFile))
200 GROUP_DeleteGroup(hGroup);
201 return(0);
205 /* FIXME shouldn't be necessary */
206 GROUP_ShowGroupWindow(hGroup);
208 return hGroup;
211 /***********************************************************************
212 * GRPFILE_ScanProgram
215 static HLOCAL GRPFILE_ScanProgram(LPCSTR buffer, INT size,
216 LPCSTR program_ptr, INT seqnum,
217 LPCSTR extension, HLOCAL hGroup,
218 LPCSTR lpszGrpFile)
220 INT icontype;
221 HICON hIcon;
222 LPCSTR lpszName, lpszCmdLine, lpszIconFile, lpszWorkDir;
223 LPCSTR iconinfo_ptr, iconANDbits_ptr, iconXORbits_ptr;
224 INT x, y, nIconIndex, iconANDsize, iconXORsize;
225 INT nHotKey, nCmdShow;
226 CURSORICONINFO iconinfo;
228 x = GET_SHORT(program_ptr, 0);
229 y = GET_SHORT(program_ptr, 2);
230 nIconIndex = GET_USHORT(program_ptr, 4);
232 /* FIXME is this correct ?? */
233 icontype = GET_USHORT(program_ptr, 6);
234 switch (icontype)
236 default:
237 MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s, lpszGrpFile,
238 IDS_WARNING, MB_OK);
239 case 0x048c:
240 iconXORsize = GET_USHORT(program_ptr, 8);
241 iconANDsize = GET_USHORT(program_ptr, 10) / 8;
242 iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12);
243 iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 14);
244 iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 16);
245 iconinfo.ptHotSpot.x = GET_USHORT(iconinfo_ptr, 0);
246 iconinfo.ptHotSpot.y = GET_USHORT(iconinfo_ptr, 2);
247 iconinfo.nWidth = GET_USHORT(iconinfo_ptr, 4);
248 iconinfo.nHeight = GET_USHORT(iconinfo_ptr, 6);
249 iconinfo.nWidthBytes = GET_USHORT(iconinfo_ptr, 8);
250 iconinfo.bPlanes = GET_USHORT(iconinfo_ptr, 10);
251 iconinfo.bBitsPerPixel = GET_USHORT(iconinfo_ptr, 11);
252 break;
253 case 0x000c:
254 iconANDsize = GET_USHORT(program_ptr, 8);
255 iconXORsize = GET_USHORT(program_ptr, 10);
256 iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12);
257 iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 14);
258 iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 16);
259 iconinfo.ptHotSpot.x = GET_USHORT(iconinfo_ptr, 0);
260 iconinfo.ptHotSpot.y = GET_USHORT(iconinfo_ptr, 2);
261 iconinfo.nWidth = GET_USHORT(iconinfo_ptr, 4);
262 iconinfo.nHeight = GET_USHORT(iconinfo_ptr, 6);
263 iconinfo.nWidthBytes = GET_USHORT(iconinfo_ptr, 8) * 8;
264 iconinfo.bPlanes = GET_USHORT(iconinfo_ptr, 10);
265 iconinfo.bBitsPerPixel = GET_USHORT(iconinfo_ptr, 11);
268 if (iconANDbits_ptr + iconANDsize > buffer + size ||
269 iconXORbits_ptr + iconXORsize > buffer + size) return(0);
271 hIcon = CreateCursorIconIndirect(Globals.hInstance, &iconinfo,
272 (LPSTR)iconANDbits_ptr,
273 (LPSTR)iconXORbits_ptr);
275 lpszName = buffer + GET_USHORT(program_ptr, 18);
276 lpszCmdLine = buffer + GET_USHORT(program_ptr, 20);
277 lpszIconFile = buffer + GET_USHORT(program_ptr, 22);
278 if (iconinfo_ptr + 6 > buffer + size ||
279 lpszName > buffer + size ||
280 lpszCmdLine > buffer + size ||
281 lpszIconFile > buffer + size) return(0);
283 /* Scan Extensions */
284 lpszWorkDir = "";
285 nHotKey = 0;
286 nCmdShow = SW_SHOWNORMAL;
287 if (extension)
289 LPCSTR ptr = extension;
290 while (ptr + 6 <= buffer + size)
292 UINT type = GET_USHORT(ptr, 0);
293 UINT number = GET_USHORT(ptr, 2);
294 UINT skip = GET_USHORT(ptr, 4);
296 if (number == seqnum)
298 switch (type)
300 case 0x8000:
301 if (ptr + 10 > buffer + size) return(0);
302 if (ptr[6] != 'P' || ptr[7] != 'M' ||
303 ptr[8] != 'C' || ptr[9] != 'C') return(0);
304 break;
305 case 0x8101:
306 lpszWorkDir = ptr + 6;
307 break;
308 case 0x8102:
309 if (ptr + 8 > buffer + size) return(0);
310 nHotKey = GET_USHORT(ptr, 6);
311 break;
312 case 0x8103:
313 if (ptr + 8 > buffer + size) return(0);
314 nCmdShow = GET_USHORT(ptr, 6);
315 break;
316 default:
317 MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s,
318 lpszGrpFile, IDS_WARNING, MB_OK);
321 if (!skip) break;
322 ptr += skip;
326 return (PROGRAM_AddProgram(hGroup, hIcon, lpszName, x, y,
327 lpszCmdLine, lpszIconFile,
328 nIconIndex, lpszWorkDir,
329 nHotKey, nCmdShow));
332 /***********************************************************************
334 * GRPFILE_WriteGroupFile
337 BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup)
339 CHAR szPath[MAX_PATHNAME_LEN];
340 GROUP *group = LocalLock(hGroup);
341 OFSTRUCT dummy;
342 HFILE file;
343 BOOL ret;
345 GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
346 MAX_PATHNAME_LEN,
347 group->bFileNameModified);
349 /* Try not to overwrite original files */
351 /* group->bOverwriteFileOk == TRUE only if a file has the modified format */
352 if (!group->bOverwriteFileOk &&
353 OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
355 /* Original file exists, try `.gr' extension */
356 GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
357 MAX_PATHNAME_LEN, TRUE);
358 if (OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
360 /* File exists. Do not overwrite */
361 MAIN_MessageBoxIDS_s(IDS_FILE_NOT_OVERWRITTEN_s, szPath,
362 IDS_INFO, MB_OK);
363 return FALSE;
365 /* Inform about the modified file name */
366 if (IDCANCEL ==
367 MAIN_MessageBoxIDS_s(IDS_SAVE_GROUP_AS_s, szPath, IDS_INFO,
368 MB_OKCANCEL | MB_ICONINFORMATION))
369 return FALSE;
373 /* Warn about the incompatibility */
374 CHAR msg[MAX_PATHNAME_LEN + 200];
375 wsprintf(msg,
376 "Group files written by this DRAFT Program Manager "
377 "cannot be read by the Microsoft Program Manager!!\n"
378 "Are you sure to write %s?", szPath);
379 if (IDOK != MessageBox(Globals.hMainWnd, msg, "WARNING",
380 MB_OKCANCEL | MB_DEFBUTTON2)) return FALSE;
383 /* FIXME */
384 if (OpenFile(szPath, &dummy, OF_EXIST) == HFILE_ERROR)
386 CHAR msg[MAX_PATHNAME_LEN + 200];
387 wsprintf(msg, "Cause of a bug you must now touch the file %s\n", szPath);
388 MessageBox(Globals.hMainWnd, msg, "", MB_OK);
391 /* Open file */
392 file = _lopen(szPath, OF_WRITE);
393 if (file != HFILE_ERROR)
395 ret = GRPFILE_DoWriteGroupFile(file, group);
396 _lclose(file);
398 else ret = FALSE;
400 if (!ret)
401 MAIN_MessageBoxIDS_s(IDS_FILE_WRITE_ERROR_s, szPath, IDS_ERROR, MB_OK);
403 return(ret);
406 /***********************************************************************
408 * GRPFILE_CalculateSizes
411 static VOID GRPFILE_CalculateSizes(PROGRAM *program,
412 INT *Progs, INT *Icons)
414 CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
415 INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
416 INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
418 *Progs += 24;
419 *Progs += lstrlen(LocalLock(program->hName)) + 1;
420 *Progs += lstrlen(LocalLock(program->hCmdLine)) + 1;
421 *Progs += lstrlen(LocalLock(program->hIconFile)) + 1;
423 *Icons += 12; /* IconInfo */
424 *Icons += sizeAnd;
425 *Icons += sizeXor;
428 /***********************************************************************
430 * GRPFILE_DoWriteGroupFile
433 static BOOL GRPFILE_DoWriteGroupFile(HFILE file, GROUP *group)
435 BYTE buffer[34];
436 HLOCAL hProgram;
437 INT NumProg, Title, Progs, Icons, Extension;
438 INT CurrProg, CurrIcon, nCmdShow, ptr, seqnum;
439 BOOL need_extension;
440 LPCSTR lpszTitle = LocalLock(group->hName);
442 /* Calculate offsets */
443 NumProg = 0;
444 Icons = 0;
445 Extension = 0;
446 need_extension = FALSE;
447 hProgram = group->hPrograms;
448 while(hProgram)
450 PROGRAM *program = LocalLock(hProgram);
451 LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
453 NumProg++;
454 GRPFILE_CalculateSizes(program, &Icons, &Extension);
456 /* Set a flag if an extension is needed */
457 if (lpszWorkDir[0] || program->nHotKey ||
458 program->nCmdShow != SW_SHOWNORMAL) need_extension = TRUE;
460 hProgram = program->hNext;
462 Title = 34 + NumProg * 2;
463 Progs = Title + lstrlen(lpszTitle) + 1;
464 Icons += Progs;
465 Extension += Icons;
467 /* Header */
468 buffer[0] = 'P';
469 buffer[1] = 'M';
470 #if 0
471 buffer[2] = 'C'; /* Original magic number */
472 buffer[3] = 'C';
473 #else
474 buffer[2] = 'X'; /* Modified magic number: no checksum */
475 buffer[3] = 'X';
476 #endif
477 PUT_SHORT(buffer, 4, 0); /* Checksum ignored */
478 PUT_SHORT(buffer, 6, Extension);
479 /* Update group->nCmdShow */
480 if (IsIconic(group->hWnd)) nCmdShow = SW_SHOWMINIMIZED;
481 else if (IsZoomed(group->hWnd)) nCmdShow = SW_SHOWMAXIMIZED;
482 else nCmdShow = SW_SHOWNORMAL;
483 PUT_SHORT(buffer, 8, nCmdShow);
484 PUT_SHORT(buffer, 10, group->x);
485 PUT_SHORT(buffer, 12, group->y);
486 PUT_SHORT(buffer, 14, group->width);
487 PUT_SHORT(buffer, 16, group->height);
488 PUT_SHORT(buffer, 18, group->iconx);
489 PUT_SHORT(buffer, 20, group->icony);
490 PUT_SHORT(buffer, 22, Title);
491 PUT_SHORT(buffer, 24, 0x0020); /* unknown */
492 PUT_SHORT(buffer, 26, 0x0020); /* unknown */
493 PUT_SHORT(buffer, 28, 0x0108); /* unknown */
494 PUT_SHORT(buffer, 30, 0x0000); /* unknown */
495 PUT_SHORT(buffer, 32, NumProg);
497 if (HFILE_ERROR == _lwrite(file, buffer, 34)) return FALSE;
499 /* Program table */
500 CurrProg = Progs;
501 CurrIcon = Icons;
502 hProgram = group->hPrograms;
503 while(hProgram)
505 PROGRAM *program = LocalLock(hProgram);
507 PUT_SHORT(buffer, 0, CurrProg);
508 if (HFILE_ERROR == _lwrite(file, buffer, 2)) return FALSE;
510 GRPFILE_CalculateSizes(program, &CurrProg, &CurrIcon);
511 hProgram = program->hNext;
514 /* Title */
515 if (HFILE_ERROR == _lwrite(file, lpszTitle, lstrlen(lpszTitle) + 1))
516 return FALSE;
518 /* Program entries */
519 CurrProg = Progs;
520 CurrIcon = Icons;
521 hProgram = group->hPrograms;
522 while(hProgram)
524 PROGRAM *program = LocalLock(hProgram);
525 CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
526 LPCSTR Name = LocalLock(program->hName);
527 LPCSTR CmdLine = LocalLock(program->hCmdLine);
528 LPCSTR IconFile = LocalLock(program->hIconFile);
529 INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
530 INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
532 PUT_SHORT(buffer, 0, program->x);
533 PUT_SHORT(buffer, 2, program->y);
534 PUT_SHORT(buffer, 4, program->nIconIndex);
535 PUT_SHORT(buffer, 6, 0x048c); /* unknown */
536 PUT_SHORT(buffer, 8, sizeXor);
537 PUT_SHORT(buffer, 10, sizeAnd * 8);
538 PUT_SHORT(buffer, 12, CurrIcon);
539 PUT_SHORT(buffer, 14, CurrIcon + 12 + sizeAnd);
540 PUT_SHORT(buffer, 16, CurrIcon + 12);
541 ptr = CurrProg + 24;
542 PUT_SHORT(buffer, 18, ptr);
543 ptr += lstrlen(Name) + 1;
544 PUT_SHORT(buffer, 20, ptr);
545 ptr += lstrlen(CmdLine) + 1;
546 PUT_SHORT(buffer, 22, ptr);
548 if (HFILE_ERROR == _lwrite(file, buffer, 24) ||
549 HFILE_ERROR == _lwrite(file, Name, lstrlen(Name) + 1) ||
550 HFILE_ERROR == _lwrite(file, CmdLine, lstrlen(CmdLine) + 1) ||
551 HFILE_ERROR == _lwrite(file, IconFile, lstrlen(IconFile) + 1))
552 return FALSE;
554 GRPFILE_CalculateSizes(program, &CurrProg, &CurrIcon);
555 hProgram = program->hNext;
558 /* Icons */
559 hProgram = group->hPrograms;
560 while(hProgram)
562 PROGRAM *program = LocalLock(hProgram);
563 CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
564 SEGPTR XorBits, AndBits;
565 INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
566 INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
567 DumpIcon(LocalLock(program->hIcon), 0, &XorBits, &AndBits);
569 PUT_SHORT(buffer, 0, iconinfo->ptHotSpot.x);
570 PUT_SHORT(buffer, 2, iconinfo->ptHotSpot.y);
571 PUT_SHORT(buffer, 4, iconinfo->nWidth);
572 PUT_SHORT(buffer, 6, iconinfo->nHeight);
573 PUT_SHORT(buffer, 8, iconinfo->nWidthBytes);
574 buffer[10] = iconinfo->bPlanes;
575 buffer[11] = iconinfo->bBitsPerPixel;
577 if (HFILE_ERROR == _lwrite(file, buffer, 12) ||
578 HFILE_ERROR == _lwrite(file, AndBits, sizeAnd) ||
579 HFILE_ERROR == _lwrite(file, XorBits, sizeXor)) return FALSE;
581 hProgram = program->hNext;
584 if (need_extension)
586 /* write `PMCC' extension */
587 PUT_SHORT(buffer, 0, 0x8000);
588 PUT_SHORT(buffer, 2, 0xffff);
589 PUT_SHORT(buffer, 4, 0x000a);
590 buffer[6] = 'P', buffer[7] = 'M';
591 buffer[8] = 'C', buffer[9] = 'C';
592 if (HFILE_ERROR == _lwrite(file, buffer, 10)) return FALSE;
594 seqnum = 0;
595 hProgram = group->hPrograms;
596 while(hProgram)
598 PROGRAM *program = LocalLock(hProgram);
599 LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
601 /* Working directory */
602 if (lpszWorkDir[0])
604 PUT_SHORT(buffer, 0, 0x8101);
605 PUT_SHORT(buffer, 2, seqnum);
606 PUT_SHORT(buffer, 4, 7 + lstrlen(lpszWorkDir));
607 if (HFILE_ERROR == _lwrite(file, buffer, 6) ||
608 HFILE_ERROR == _lwrite(file, lpszWorkDir, lstrlen(lpszWorkDir) + 1))
609 return FALSE;
612 /* Hot key */
613 if (program->nHotKey)
615 PUT_SHORT(buffer, 0, 0x8102);
616 PUT_SHORT(buffer, 2, seqnum);
617 PUT_SHORT(buffer, 4, 8);
618 PUT_SHORT(buffer, 6, program->nHotKey);
619 if (HFILE_ERROR == _lwrite(file, buffer, 8)) return FALSE;
622 /* Show command */
623 if (program->nCmdShow)
625 PUT_SHORT(buffer, 0, 0x8103);
626 PUT_SHORT(buffer, 2, seqnum);
627 PUT_SHORT(buffer, 4, 8);
628 PUT_SHORT(buffer, 6, program->nCmdShow);
629 if (HFILE_ERROR == _lwrite(file, buffer, 8)) return FALSE;
632 seqnum++;
633 hProgram = program->hNext;
636 /* Write `End' extension */
637 PUT_SHORT(buffer, 0, 0xffff);
638 PUT_SHORT(buffer, 2, 0xffff);
639 PUT_SHORT(buffer, 4, 0x0000);
640 if (HFILE_ERROR == _lwrite(file, buffer, 6)) return FALSE;
643 return TRUE;
646 /* Local Variables: */
647 /* c-file-style: "GNU" */
648 /* End: */