~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/programs/progman/grpfile.c

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Program Manager
  3  *
  4  * Copyright 1996 Ulrich Schmid
  5  *           1997 Peter Schlaile
  6  *
  7  * This library is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU Lesser General Public
  9  * License as published by the Free Software Foundation; either
 10  * version 2.1 of the License, or (at your option) any later version.
 11  *
 12  * This library is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  * Lesser General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU Lesser General Public
 18  * License along with this library; if not, write to the Free Software
 19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 20  */
 21 
 22 #define WIN32_LEAN_AND_MEAN
 23 
 24 #include "windows.h"
 25 #include "progman.h"
 26 #include "mmsystem.h"
 27 
 28 #define MALLOCHUNK 1000
 29 
 30 #define GET_USHORT(buffer, i)\
 31   (((BYTE)((buffer)[(i)]) + 0x100 * (BYTE)((buffer)[(i)+1])))
 32 #define GET_SHORT(buffer, i)\
 33   (((BYTE)((buffer)[(i)]) + 0x100 * (signed char)((buffer)[(i)+1])))
 34 #define PUT_SHORT(buffer, i, s)\
 35   (((buffer)[(i)] = (s) & 0xff, (buffer)[(i)+1] = ((s) >> 8) & 0xff))
 36 
 37 static BOOL   GRPFILE_ReadFileToBuffer(LPCSTR, HLOCAL*, INT*);
 38 static HLOCAL GRPFILE_ScanGroup(LPCSTR, INT, LPCSTR, BOOL);
 39 static HLOCAL GRPFILE_ScanProgram(LPCSTR, INT, LPCSTR, INT,
 40                                   LPCSTR, HLOCAL,LPCSTR);
 41 static BOOL GRPFILE_DoWriteGroupFile(HFILE file, PROGGROUP *group);
 42 
 43 /***********************************************************************
 44  *
 45  *           GRPFILE_ModifyFileName
 46  *
 47  *  Change extension `.grp' to `.gr'
 48  */
 49 
 50 static VOID GRPFILE_ModifyFileName(LPSTR lpszNewName, LPCSTR lpszOrigName,
 51                                    INT nSize, BOOL bModify)
 52 {
 53   lstrcpynA(lpszNewName, lpszOrigName, nSize);
 54   lpszNewName[nSize-1] = '\0';
 55   if (!bModify) return;
 56   if (!lstrcmpiA(lpszNewName + strlen(lpszNewName) - 4, ".grp"))
 57     lpszNewName[strlen(lpszNewName) - 1] = '\0';
 58 }
 59 
 60 /***********************************************************************
 61  *
 62  *           GRPFILE_ReadGroupFile
 63  */
 64 
 65 HLOCAL GRPFILE_ReadGroupFile(LPCSTR lpszPath)
 66 {
 67   CHAR   szPath_gr[MAX_PATHNAME_LEN];
 68   BOOL   bFileNameModified = FALSE;
 69   OFSTRUCT dummy;
 70   HLOCAL hBuffer, hGroup;
 71   INT    size;
 72 
 73   /* if `.gr' file exists use that */
 74   GRPFILE_ModifyFileName(szPath_gr, lpszPath, MAX_PATHNAME_LEN, TRUE);
 75   if (OpenFile(szPath_gr, &dummy, OF_EXIST) != HFILE_ERROR)
 76     {
 77       lpszPath = szPath_gr;
 78       bFileNameModified = TRUE;
 79     }
 80 
 81   /* Read the whole file into a buffer */
 82   if (!GRPFILE_ReadFileToBuffer(lpszPath, &hBuffer, &size))
 83     {
 84       MAIN_MessageBoxIDS_s(IDS_GRPFILE_READ_ERROR_s, lpszPath, IDS_ERROR, MB_YESNO);
 85       return(0);
 86     }
 87 
 88   /* Interpret buffer */
 89   hGroup = GRPFILE_ScanGroup(LocalLock(hBuffer), size,
 90                              lpszPath, bFileNameModified);
 91   if (!hGroup)
 92     MAIN_MessageBoxIDS_s(IDS_GRPFILE_READ_ERROR_s, lpszPath, IDS_ERROR, MB_YESNO);
 93 
 94   LocalFree(hBuffer);
 95 
 96   return(hGroup);
 97 }
 98 
 99 /***********************************************************************
100  *
101  *           GRPFILE_ReadFileToBuffer
102  */
103 
104 static BOOL GRPFILE_ReadFileToBuffer(LPCSTR path, HLOCAL *phBuffer,
105                                      INT *piSize)
106 {
107   UINT    len, size;
108   LPSTR  buffer;
109   HLOCAL hBuffer, hNewBuffer;
110   HFILE  file;
111 
112   file=_lopen(path, OF_READ);
113   if (file == HFILE_ERROR) return FALSE;
114 
115   size = 0;
116   hBuffer = LocalAlloc(LMEM_FIXED, MALLOCHUNK + 1);
117   if (!hBuffer) return FALSE;
118   buffer = LocalLock(hBuffer);
119 
120   while ((len = _lread(file, buffer + size, MALLOCHUNK))
121          == MALLOCHUNK)
122     {
123       size += len;
124       hNewBuffer = LocalReAlloc(hBuffer, size + MALLOCHUNK + 1,
125                                 LMEM_FIXED);
126       if (!hNewBuffer)
127         {
128           LocalFree(hBuffer);
129           return FALSE;
130         }
131       hBuffer = hNewBuffer;
132       buffer = LocalLock(hBuffer);
133     }
134 
135   _lclose(file);
136 
137   if (len == (UINT)HFILE_ERROR)
138     {
139       LocalFree(hBuffer);
140       return FALSE;
141     }
142 
143   size += len;
144   buffer[size] = 0;
145 
146   *phBuffer = hBuffer;
147   *piSize   = size;
148   return TRUE;
149 }
150 
151 /***********************************************************************
152  *           GRPFILE_ScanGroup
153  */
154 
155 static HLOCAL GRPFILE_ScanGroup(LPCSTR buffer, INT size,
156                                 LPCSTR lpszGrpFile,
157                                 BOOL bModifiedFileName)
158 {
159   HLOCAL  hGroup;
160   INT     i, seqnum;
161   LPCSTR  extension;
162   LPCSTR  lpszName;
163   INT     x, y, width, height, iconx, icony, nCmdShow;
164   INT     number_of_programs;
165   BOOL    bOverwriteFileOk;
166 
167   if (buffer[0] != 'P' || buffer[1] != 'M') return(0);
168   if (buffer[2] == 'C' && buffer[3] == 'C')
169     /* original with checksum */
170     bOverwriteFileOk = FALSE;
171   else if (buffer[2] == 'X' && buffer[3] == 'X')
172     /* modified without checksum */
173     bOverwriteFileOk = TRUE;
174   else return(0);
175 
176   /* checksum = GET_USHORT(buffer, 4)   (ignored) */
177 
178   extension = buffer + GET_USHORT(buffer, 6);
179   if (extension == buffer + size) extension = 0;
180   else if (extension + 6 > buffer + size) return(0);
181 
182   nCmdShow = GET_USHORT(buffer,  8);
183   x        = GET_SHORT(buffer,  10);
184   y        = GET_SHORT(buffer,  12);
185   width    = GET_USHORT(buffer, 14);
186   height   = GET_USHORT(buffer, 16);
187   iconx    = GET_SHORT(buffer,  18);
188   icony    = GET_SHORT(buffer,  20);
189   lpszName = buffer + GET_USHORT(buffer, 22);
190   if (lpszName >= buffer + size) return(0);
191 
192   /* unknown bytes 24 - 31 ignored */
193   /*
194     Unknown bytes should be:
195     wLogPixelsX = GET_SHORT(buffer, 24);
196     wLogPixelsY = GET_SHORT(buffer, 26);
197     byBitsPerPixel = byte at 28;
198     byPlanes     = byte at 29;
199     wReserved   = GET_SHORT(buffer, 30);
200     */
201 
202   hGroup = GROUP_AddGroup(lpszName, lpszGrpFile, nCmdShow, x, y,
203                           width, height, iconx, icony,
204                           bModifiedFileName, bOverwriteFileOk,
205                           TRUE);
206   if (!hGroup) return(0);
207 
208   number_of_programs = GET_USHORT(buffer, 32);
209   if (2 * number_of_programs + 34 > size) return(0);
210   for (i=0, seqnum=0; i < number_of_programs; i++, seqnum++)
211     {
212       LPCSTR program_ptr = buffer + GET_USHORT(buffer, 34 + 2*i);
213       if (program_ptr + 24 > buffer + size) return(0);
214       if (!GET_USHORT(buffer, 34 + 2*i)) continue;
215       if (!GRPFILE_ScanProgram(buffer, size, program_ptr, seqnum,
216                                extension, hGroup, lpszGrpFile))
217         {
218           GROUP_DeleteGroup(hGroup);
219           return(0);
220         }
221     }
222 
223   /* FIXME shouldn't be necessary */
224   GROUP_ShowGroupWindow(hGroup);
225 
226   return hGroup;
227 }
228 
229 /***********************************************************************
230  *           GRPFILE_ScanProgram
231  */
232 
233 static HLOCAL GRPFILE_ScanProgram(LPCSTR buffer, INT size,
234                                   LPCSTR program_ptr, INT seqnum,
235                                   LPCSTR extension, HLOCAL hGroup,
236                                   LPCSTR lpszGrpFile)
237 {
238   INT    icontype;
239   HICON  hIcon;
240   LPCSTR lpszName, lpszCmdLine, lpszIconFile, lpszWorkDir;
241   LPCSTR iconinfo_ptr, iconANDbits_ptr, iconXORbits_ptr;
242   INT    x, y, nIconIndex, iconANDsize, iconXORsize;
243   INT    nHotKey, nCmdShow;
244   UINT width, height, planes, bpp;
245 
246   x               = GET_SHORT(program_ptr, 0);
247   y               = GET_SHORT(program_ptr, 2);
248   nIconIndex      = GET_USHORT(program_ptr, 4);
249 
250   /* FIXME is this correct ?? */
251   icontype = GET_USHORT(program_ptr,  6);
252   switch (icontype)
253     {
254     default:
255       MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s, lpszGrpFile,
256                            IDS_WARNING, MB_OK);
257     case 0x048c:
258       iconXORsize     = GET_USHORT(program_ptr,  8);
259       iconANDsize     = GET_USHORT(program_ptr, 10) / 8;
260       iconinfo_ptr    = buffer + GET_USHORT(program_ptr, 12);
261       iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 14);
262       iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 16);
263       width           = GET_USHORT(iconinfo_ptr, 4);
264       height          = GET_USHORT(iconinfo_ptr, 6);
265       planes          = GET_USHORT(iconinfo_ptr, 10);
266       bpp             = GET_USHORT(iconinfo_ptr, 11);
267       break;
268     case 0x000c:
269       iconANDsize     = GET_USHORT(program_ptr,  8);
270       iconXORsize     = GET_USHORT(program_ptr, 10);
271       iconinfo_ptr    = buffer + GET_USHORT(program_ptr, 12);
272       iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 14);
273       iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 16);
274       width           = GET_USHORT(iconinfo_ptr, 4);
275       height          = GET_USHORT(iconinfo_ptr, 6);
276       planes          = GET_USHORT(iconinfo_ptr, 10);
277       bpp             = GET_USHORT(iconinfo_ptr, 11);
278     }
279 
280   if (iconANDbits_ptr + iconANDsize > buffer + size ||
281       iconXORbits_ptr + iconXORsize > buffer + size) return(0);
282 
283   hIcon = CreateIcon( Globals.hInstance, width, height, planes, bpp, iconANDbits_ptr, iconXORbits_ptr );
284 
285   lpszName        = buffer + GET_USHORT(program_ptr, 18);
286   lpszCmdLine     = buffer + GET_USHORT(program_ptr, 20);
287   lpszIconFile    = buffer + GET_USHORT(program_ptr, 22);
288   if (iconinfo_ptr + 6 > buffer + size ||
289       lpszName         > buffer + size ||
290       lpszCmdLine      > buffer + size ||
291       lpszIconFile     > buffer + size) return(0);
292 
293   /* Scan Extensions */
294   lpszWorkDir = "";
295   nHotKey     = 0;
296   nCmdShow    = SW_SHOWNORMAL;
297   if (extension)
298     {
299       LPCSTR ptr = extension;
300       while (ptr + 6 <= buffer + size)
301         {
302           UINT type   = GET_USHORT(ptr, 0);
303           UINT number = GET_USHORT(ptr, 2);
304           UINT skip   = GET_USHORT(ptr, 4);
305 
306           if (number == seqnum)
307             {
308               switch (type)
309                 {
310                 case 0x8000:
311                   if (ptr + 10 > buffer + size) return(0);
312                   if (ptr[6] != 'P' || ptr[7] != 'M' ||
313                       ptr[8] != 'C' || ptr[9] != 'C') return(0);
314                   break;
315                 case 0x8101:
316                   lpszWorkDir = ptr + 6;
317                   break;
318                 case 0x8102:
319                   if (ptr + 8 > buffer + size) return(0);
320                   nHotKey = GET_USHORT(ptr, 6);
321                   break;
322                 case 0x8103:
323                   if (ptr + 8 > buffer + size) return(0);
324                   nCmdShow = GET_USHORT(ptr, 6);
325                   break;
326                 default:
327                   MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s,
328                                        lpszGrpFile, IDS_WARNING, MB_OK);
329                 }
330             }
331           if (!skip) break;
332           ptr += skip;
333         }
334     }
335 
336   return (PROGRAM_AddProgram(hGroup, hIcon, lpszName, x, y,
337                              lpszCmdLine, lpszIconFile,
338                              nIconIndex, lpszWorkDir,
339                              nHotKey, nCmdShow));
340 }
341 
342 /***********************************************************************
343  *
344  *           GRPFILE_WriteGroupFile
345  */
346 
347 BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup)
348 {
349   CHAR szPath[MAX_PATHNAME_LEN];
350   PROGGROUP *group = LocalLock(hGroup);
351   OFSTRUCT dummy;
352   HFILE file;
353   BOOL ret;
354 
355   GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
356                          MAX_PATHNAME_LEN,
357                          group->bFileNameModified);
358 
359   /* Try not to overwrite original files */
360 
361   /* group->bOverwriteFileOk == TRUE only if a file has the modified format */
362   if (!group->bOverwriteFileOk &&
363       OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
364     {
365       /* Original file exists, try `.gr' extension */
366       GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
367                              MAX_PATHNAME_LEN, TRUE);
368       if (OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
369         {
370           /* File exists. Do not overwrite */
371           MAIN_MessageBoxIDS_s(IDS_FILE_NOT_OVERWRITTEN_s, szPath,
372                                IDS_INFO, MB_OK);
373           return FALSE;
374         }
375       /* Inform about the modified file name */
376       if (IDCANCEL ==
377           MAIN_MessageBoxIDS_s(IDS_SAVE_GROUP_AS_s, szPath, IDS_INFO,
378                                MB_OKCANCEL | MB_ICONINFORMATION))
379         return FALSE;
380     }
381 
382   {
383     /* Warn about the (possible) incompatibility */
384     CHAR msg[MAX_PATHNAME_LEN + 200];
385     wsprintfA(msg,
386              "Group files written by this DRAFT Program Manager "
387              "possibly cannot be read by the Microsoft Program Manager!!\n"
388              "Are you sure to write %s?", szPath);
389     if (IDOK != MessageBoxA(Globals.hMainWnd, msg, "WARNING",
390                             MB_OKCANCEL | MB_DEFBUTTON2)) return FALSE;
391   }
392 
393   /* Open file */
394   file = _lcreat(szPath, 0);
395   if (file != HFILE_ERROR)
396     {
397       ret = GRPFILE_DoWriteGroupFile(file, group);
398       _lclose(file);
399     }
400   else ret = FALSE;
401 
402   if (!ret)
403     MAIN_MessageBoxIDS_s(IDS_FILE_WRITE_ERROR_s, szPath, IDS_ERROR, MB_OK);
404 
405   return(ret);
406 }
407 
408 /***********************************************************************
409  *
410  *           GRPFILE_CalculateSizes
411  */
412 
413 static VOID GRPFILE_CalculateSizes(PROGRAM *program, INT *Progs, INT *Icons,
414                                    UINT *sizeAnd, UINT *sizeXor)
415 {
416   ICONINFO info;
417   BITMAP bmp;
418 
419   GetIconInfo( program->hIcon, &info );
420   GetObjectW( info.hbmMask, sizeof(bmp), &bmp );
421   *sizeAnd = bmp.bmHeight * ((bmp.bmWidth + 15) / 16 * 2);
422   GetObjectW( info.hbmColor, sizeof(bmp), &bmp );
423   *sizeXor = bmp.bmHeight * bmp.bmWidthBytes;
424   DeleteObject( info.hbmMask );
425   DeleteObject( info.hbmColor );
426 
427   *Progs += 24;
428   *Progs += strlen(LocalLock(program->hName)) + 1;
429   *Progs += strlen(LocalLock(program->hCmdLine)) + 1;
430   *Progs += strlen(LocalLock(program->hIconFile)) + 1;
431 
432   *Icons += 12; /* IconInfo */
433   *Icons += *sizeAnd;
434   *Icons += *sizeXor;
435 }
436 
437 /***********************************************************************/
438 UINT16 GRPFILE_checksum;
439 BOOL GRPFILE_checksum_half_word;
440 BYTE GRPFILE_checksum_last_byte;
441 /***********************************************************************
442  *
443  *           GRPFILE_InitChecksum
444  */
445 
446 static void GRPFILE_InitChecksum(void)
447 {
448         GRPFILE_checksum = 0;
449         GRPFILE_checksum_half_word = 0;
450 }
451 
452 /***********************************************************************
453  *
454  *           GRPFILE_GetChecksum
455  */
456 
457 static UINT16 GRPFILE_GetChecksum(void)
458 {
459         return GRPFILE_checksum;
460 }
461 
462 /***********************************************************************
463  *
464  *           GRPFILE_WriteWithChecksum
465  *
466  * Looks crazier than it is:
467  *
468  * chksum = 0;
469  * chksum = cksum - 1. word;
470  * chksum = cksum - 2. word;
471  * ...
472  *
473  * if (filelen is even)
474  *      great I'm finished
475  * else
476  *      ignore last byte
477  */
478 
479 static UINT GRPFILE_WriteWithChecksum(HFILE file, LPCSTR str, UINT size)
480 {
481         UINT i;
482         if (GRPFILE_checksum_half_word) {
483                 GRPFILE_checksum -= GRPFILE_checksum_last_byte;
484         }
485         for (i=0; i < size; i++) {
486                 if (GRPFILE_checksum_half_word) {
487                         GRPFILE_checksum -= str[i] << 8;
488                 } else {
489                         GRPFILE_checksum -= str[i];
490                 }
491                 GRPFILE_checksum_half_word ^= 1;
492         }
493 
494         if (GRPFILE_checksum_half_word) {
495                 GRPFILE_checksum_last_byte = str[size-1];
496                 GRPFILE_checksum += GRPFILE_checksum_last_byte;
497         }
498 
499         return _lwrite(file, str, size);
500 }
501 
502 
503 /***********************************************************************
504  *
505  *           GRPFILE_DoWriteGroupFile
506  */
507 
508 static BOOL GRPFILE_DoWriteGroupFile(HFILE file, PROGGROUP *group)
509 {
510   CHAR buffer[34];
511   HLOCAL hProgram;
512   INT    NumProg, Title, Progs, Icons, Extension;
513   INT    CurrProg, CurrIcon, nCmdShow, ptr, seqnum;
514   DWORD  sizeAnd, sizeXor;
515   BOOL   need_extension;
516   LPCSTR lpszTitle = LocalLock(group->hName);
517 
518   UINT16 checksum;
519 
520   GRPFILE_InitChecksum();
521 
522   /* Calculate offsets */
523   NumProg = 0;
524   Icons   = 0;
525   Extension = 0;
526   need_extension = FALSE;
527   hProgram = group->hPrograms;
528   while(hProgram)
529     {
530       PROGRAM *program = LocalLock(hProgram);
531       LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
532 
533       NumProg++;
534       GRPFILE_CalculateSizes(program, &Icons, &Extension, &sizeAnd, &sizeXor);
535 
536       /* Set a flag if an extension is needed */
537       if (lpszWorkDir[0] || program->nHotKey ||
538           program->nCmdShow != SW_SHOWNORMAL) need_extension = TRUE;
539 
540       hProgram = program->hNext;
541     }
542   Title      = 34 + NumProg * 2;
543   Progs      = Title + strlen(lpszTitle) + 1;
544   Icons     += Progs;
545   Extension += Icons;
546 
547   /* Header */
548   buffer[0] = 'P';
549   buffer[1] = 'M';
550   buffer[2] = 'C';
551   buffer[3] = 'C';
552 
553   PUT_SHORT(buffer,  4, 0); /* Checksum zero for now, written later */
554   PUT_SHORT(buffer,  6, Extension);
555   /* Update group->nCmdShow */
556   if (IsIconic(group->hWnd))      nCmdShow = SW_SHOWMINIMIZED;
557   else if (IsZoomed(group->hWnd)) nCmdShow = SW_SHOWMAXIMIZED;
558   else                            nCmdShow = SW_SHOWNORMAL;
559   PUT_SHORT(buffer,  8, nCmdShow);
560   PUT_SHORT(buffer, 10, group->x);
561   PUT_SHORT(buffer, 12, group->y);
562   PUT_SHORT(buffer, 14, group->width);
563   PUT_SHORT(buffer, 16, group->height);
564   PUT_SHORT(buffer, 18, group->iconx);
565   PUT_SHORT(buffer, 20, group->icony);
566   PUT_SHORT(buffer, 22, Title);
567   PUT_SHORT(buffer, 24, 0x0020); /* unknown */
568   PUT_SHORT(buffer, 26, 0x0020); /* unknown */
569   PUT_SHORT(buffer, 28, 0x0108); /* unknown */
570   PUT_SHORT(buffer, 30, 0x0000); /* unknown */
571   PUT_SHORT(buffer, 32, NumProg);
572 
573   if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 34)) return FALSE;
574 
575   /* Program table */
576   CurrProg = Progs;
577   CurrIcon = Icons;
578   hProgram = group->hPrograms;
579   while(hProgram)
580     {
581       PROGRAM *program = LocalLock(hProgram);
582 
583       PUT_SHORT(buffer, 0, CurrProg);
584       if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 2))
585               return FALSE;
586 
587       GRPFILE_CalculateSizes(program, &CurrProg, &CurrIcon, &sizeAnd, &sizeXor);
588       hProgram = program->hNext;
589     }
590 
591   /* Title */
592   if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, lpszTitle, strlen(lpszTitle) + 1))
593     return FALSE;
594 
595   /* Program entries */
596   CurrProg = Progs;
597   CurrIcon = Icons;
598   hProgram = group->hPrograms;
599   while(hProgram)
600     {
601       PROGRAM *program = LocalLock(hProgram);
602       LPCSTR Name     = LocalLock(program->hName);
603       LPCSTR CmdLine  = LocalLock(program->hCmdLine);
604       LPCSTR IconFile = LocalLock(program->hIconFile);
605       INT next_prog = CurrProg;
606       INT next_icon = CurrIcon;
607 
608       GRPFILE_CalculateSizes(program, &next_prog, &next_icon, &sizeAnd, &sizeXor);
609       PUT_SHORT(buffer,  0, program->x);
610       PUT_SHORT(buffer,  2, program->y);
611       PUT_SHORT(buffer,  4, program->nIconIndex);
612       PUT_SHORT(buffer,  6, 0x048c);            /* unknown */
613       PUT_SHORT(buffer,  8, sizeXor);
614       PUT_SHORT(buffer, 10, sizeAnd * 8);
615       PUT_SHORT(buffer, 12, CurrIcon);
616       PUT_SHORT(buffer, 14, CurrIcon + 12 + sizeAnd);
617       PUT_SHORT(buffer, 16, CurrIcon + 12);
618       ptr = CurrProg + 24;
619       PUT_SHORT(buffer, 18, ptr);
620       ptr += strlen(Name) + 1;
621       PUT_SHORT(buffer, 20, ptr);
622       ptr += strlen(CmdLine) + 1;
623       PUT_SHORT(buffer, 22, ptr);
624 
625       if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 24) ||
626           (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, Name, strlen(Name) + 1) ||
627           (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, CmdLine, strlen(CmdLine) + 1) ||
628           (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, IconFile, strlen(IconFile) + 1))
629         return FALSE;
630 
631       CurrProg = next_prog;
632       CurrIcon = next_icon;
633       hProgram = program->hNext;
634     }
635 
636   /* Icons */
637 #if 0  /* FIXME: this is broken anyway */
638   hProgram = group->hPrograms;
639   while(hProgram)
640     {
641       PROGRAM *program = LocalLock(hProgram);
642       CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
643       LPVOID XorBits, AndBits;
644       INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
645       INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
646       /* DumpIcon16(LocalLock(program->hIcon), 0, &XorBits, &AndBits);*/
647 
648       PUT_SHORT(buffer, 0, iconinfo->ptHotSpot.x);
649       PUT_SHORT(buffer, 2, iconinfo->ptHotSpot.y);
650       PUT_SHORT(buffer, 4, iconinfo->nWidth);
651       PUT_SHORT(buffer, 6, iconinfo->nHeight);
652       PUT_SHORT(buffer, 8, iconinfo->nWidthBytes);
653       buffer[10] = iconinfo->bPlanes;
654       buffer[11] = iconinfo->bBitsPerPixel;
655 
656       if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 12) ||
657           (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, AndBits, sizeAnd) ||
658           (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, XorBits, sizeXor)) return FALSE;
659 
660       hProgram = program->hNext;
661     }
662 #endif
663 
664   if (need_extension)
665     {
666       /* write `PMCC' extension */
667       PUT_SHORT(buffer, 0, 0x8000);
668       PUT_SHORT(buffer, 2, 0xffff);
669       PUT_SHORT(buffer, 4, 0x000a);
670       buffer[6] = 'P', buffer[7] = 'M';
671       buffer[8] = 'C', buffer[9] = 'C';
672       if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 10))
673               return FALSE;
674 
675       seqnum = 0;
676       hProgram = group->hPrograms;
677       while(hProgram)
678         {
679           PROGRAM *program = LocalLock(hProgram);
680           LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
681 
682           /* Working directory */
683           if (lpszWorkDir[0])
684             {
685               PUT_SHORT(buffer, 0, 0x8101);
686               PUT_SHORT(buffer, 2, seqnum);
687               PUT_SHORT(buffer, 4, 7 + strlen(lpszWorkDir));
688               if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 6) ||
689                   (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, lpszWorkDir, strlen(lpszWorkDir) + 1))
690                 return FALSE;
691             }
692 
693           /* Hot key */
694           if (program->nHotKey)
695             {
696               PUT_SHORT(buffer, 0, 0x8102);
697               PUT_SHORT(buffer, 2, seqnum);
698               PUT_SHORT(buffer, 4, 8);
699               PUT_SHORT(buffer, 6, program->nHotKey);
700               if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 8)) return FALSE;
701             }
702 
703           /* Show command */
704           if (program->nCmdShow)
705             {
706               PUT_SHORT(buffer, 0, 0x8103);
707               PUT_SHORT(buffer, 2, seqnum);
708               PUT_SHORT(buffer, 4, 8);
709               PUT_SHORT(buffer, 6, program->nCmdShow);
710               if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 8)) return FALSE;
711             }
712 
713           seqnum++;
714           hProgram = program->hNext;
715         }
716 
717       /* Write `End' extension */
718       PUT_SHORT(buffer, 0, 0xffff);
719       PUT_SHORT(buffer, 2, 0xffff);
720       PUT_SHORT(buffer, 4, 0x0000);
721       if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 6)) return FALSE;
722     }
723 
724   checksum = GRPFILE_GetChecksum();
725   _llseek(file, 4, SEEK_SET);
726   PUT_SHORT(buffer, 0, checksum);
727   _lwrite(file, buffer, 2);
728 
729   return TRUE;
730 }
731 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.