123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731 |
- /*
- * Program Manager
- *
- * Copyright 1996 Ulrich Schmid
- * 1997 Peter Schlaile
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
- #define WIN32_LEAN_AND_MEAN
- #include "windows.h"
- #include "progman.h"
- #include "mmsystem.h"
- #define MALLOCHUNK 1000
- #define GET_USHORT(buffer, i)\
- (((BYTE)((buffer)[(i)]) + 0x100 * (BYTE)((buffer)[(i)+1])))
- #define GET_SHORT(buffer, i)\
- (((BYTE)((buffer)[(i)]) + 0x100 * (signed char)((buffer)[(i)+1])))
- #define PUT_SHORT(buffer, i, s)\
- (((buffer)[(i)] = (BYTE)((s) & 0xff), (buffer)[(i)+1] = (BYTE)(((s) >> 8) & 0xff)))
- static BOOL GRPFILE_ReadFileToBuffer(LPCSTR, HLOCAL*, INT*);
- static HLOCAL GRPFILE_ScanGroup(LPCSTR, INT, LPCSTR, BOOL);
- static HLOCAL GRPFILE_ScanProgram(LPCSTR, INT, LPCSTR, INT,
- LPCSTR, HLOCAL,LPCSTR);
- static BOOL GRPFILE_DoWriteGroupFile(HFILE file, PROGGROUP *group);
- /***********************************************************************
- *
- * GRPFILE_ModifyFileName
- *
- * Change extension `.grp' to `.gr'
- */
- static VOID GRPFILE_ModifyFileName(LPSTR lpszNewName, LPCSTR lpszOrigName,
- INT nSize, BOOL bModify)
- {
- lstrcpynA(lpszNewName, lpszOrigName, nSize);
- lpszNewName[nSize-1] = '\0';
- if (!bModify) return;
- if (!lstrcmpiA(lpszNewName + strlen(lpszNewName) - 4, ".grp"))
- lpszNewName[strlen(lpszNewName) - 1] = '\0';
- }
- /***********************************************************************
- *
- * GRPFILE_ReadGroupFile
- */
- HLOCAL GRPFILE_ReadGroupFile(LPCSTR lpszPath)
- {
- CHAR szPath_gr[MAX_PATHNAME_LEN];
- BOOL bFileNameModified = FALSE;
- OFSTRUCT dummy;
- HLOCAL hBuffer, hGroup;
- INT size;
- /* if `.gr' file exists use that */
- GRPFILE_ModifyFileName(szPath_gr, lpszPath, MAX_PATHNAME_LEN, TRUE);
- if (OpenFile(szPath_gr, &dummy, OF_EXIST) != HFILE_ERROR)
- {
- lpszPath = szPath_gr;
- bFileNameModified = TRUE;
- }
- /* Read the whole file into a buffer */
- if (!GRPFILE_ReadFileToBuffer(lpszPath, &hBuffer, &size))
- {
- MAIN_MessageBoxIDS_s(IDS_GRPFILE_READ_ERROR_s, lpszPath, IDS_ERROR, MB_YESNO);
- return(0);
- }
- /* Interpret buffer */
- hGroup = GRPFILE_ScanGroup(LocalLock(hBuffer), size,
- lpszPath, bFileNameModified);
- if (!hGroup)
- MAIN_MessageBoxIDS_s(IDS_GRPFILE_READ_ERROR_s, lpszPath, IDS_ERROR, MB_YESNO);
- LocalFree(hBuffer);
- return(hGroup);
- }
- /***********************************************************************
- *
- * GRPFILE_ReadFileToBuffer
- */
- static BOOL GRPFILE_ReadFileToBuffer(LPCSTR path, HLOCAL *phBuffer,
- INT *piSize)
- {
- UINT len, size;
- LPSTR buffer;
- HLOCAL hBuffer, hNewBuffer;
- HFILE file;
- file=_lopen(path, OF_READ);
- if (file == HFILE_ERROR) return FALSE;
- size = 0;
- hBuffer = LocalAlloc(LMEM_FIXED, MALLOCHUNK + 1);
- if (!hBuffer) return FALSE;
- buffer = LocalLock(hBuffer);
- while ((len = _lread(file, buffer + size, MALLOCHUNK))
- == MALLOCHUNK)
- {
- size += len;
- hNewBuffer = LocalReAlloc(hBuffer, size + MALLOCHUNK + 1,
- LMEM_MOVEABLE);
- if (!hNewBuffer)
- {
- LocalFree(hBuffer);
- return FALSE;
- }
- hBuffer = hNewBuffer;
- buffer = LocalLock(hBuffer);
- }
- _lclose(file);
- if (len == (UINT)HFILE_ERROR)
- {
- LocalFree(hBuffer);
- return FALSE;
- }
- size += len;
- buffer[size] = 0;
- *phBuffer = hBuffer;
- *piSize = size;
- return TRUE;
- }
- /***********************************************************************
- * GRPFILE_ScanGroup
- */
- static HLOCAL GRPFILE_ScanGroup(LPCSTR buffer, INT size,
- LPCSTR lpszGrpFile,
- BOOL bModifiedFileName)
- {
- HLOCAL hGroup;
- INT i, seqnum;
- LPCSTR extension;
- LPCSTR lpszName;
- INT x, y, width, height, iconx, icony, nCmdShow;
- INT number_of_programs;
- BOOL bOverwriteFileOk;
- if (buffer[0] != 'P' || buffer[1] != 'M') return(0);
- if (buffer[2] == 'C' && buffer[3] == 'C')
- /* original with checksum */
- bOverwriteFileOk = FALSE;
- else if (buffer[2] == 'X' && buffer[3] == 'X')
- /* modified without checksum */
- bOverwriteFileOk = TRUE;
- else return(0);
- /* checksum = GET_USHORT(buffer, 4) (ignored) */
- extension = buffer + GET_USHORT(buffer, 6);
- if (extension == buffer + size) extension = 0;
- else if (extension + 6 > buffer + size) return(0);
- nCmdShow = GET_USHORT(buffer, 8);
- x = GET_SHORT(buffer, 10);
- y = GET_SHORT(buffer, 12);
- width = GET_USHORT(buffer, 14);
- height = GET_USHORT(buffer, 16);
- iconx = GET_SHORT(buffer, 18);
- icony = GET_SHORT(buffer, 20);
- lpszName = buffer + GET_USHORT(buffer, 22);
- if (lpszName >= buffer + size) return(0);
- /* unknown bytes 24 - 31 ignored */
- /*
- Unknown bytes should be:
- wLogPixelsX = GET_SHORT(buffer, 24);
- wLogPixelsY = GET_SHORT(buffer, 26);
- byBitsPerPixel = byte at 28;
- byPlanes = byte at 29;
- wReserved = GET_SHORT(buffer, 30);
- */
- hGroup = GROUP_AddGroup(lpszName, lpszGrpFile, nCmdShow, x, y,
- width, height, iconx, icony,
- bModifiedFileName, bOverwriteFileOk,
- TRUE);
- if (!hGroup) return(0);
- number_of_programs = GET_USHORT(buffer, 32);
- if (2 * number_of_programs + 34 > size) return(0);
- for (i=0, seqnum=0; i < number_of_programs; i++, seqnum++)
- {
- LPCSTR program_ptr = buffer + GET_USHORT(buffer, 34 + 2*i);
- if (program_ptr + 24 > buffer + size) return(0);
- if (!GET_USHORT(buffer, 34 + 2*i)) continue;
- if (!GRPFILE_ScanProgram(buffer, size, program_ptr, seqnum,
- extension, hGroup, lpszGrpFile))
- {
- GROUP_DeleteGroup(hGroup);
- return(0);
- }
- }
- /* FIXME shouldn't be necessary */
- GROUP_ShowGroupWindow(hGroup);
- return hGroup;
- }
- /***********************************************************************
- * GRPFILE_ScanProgram
- */
- static HLOCAL GRPFILE_ScanProgram(LPCSTR buffer, INT size,
- LPCSTR program_ptr, INT seqnum,
- LPCSTR extension, HLOCAL hGroup,
- LPCSTR lpszGrpFile)
- {
- INT icontype;
- HICON hIcon;
- LPCSTR lpszName, lpszCmdLine, lpszIconFile, lpszWorkDir;
- LPCSTR iconinfo_ptr, iconANDbits_ptr, iconXORbits_ptr;
- INT x, y, nIconIndex, iconANDsize, iconXORsize;
- INT nHotKey, nCmdShow;
- UINT width, height, planes, bpp;
- x = GET_SHORT(program_ptr, 0);
- y = GET_SHORT(program_ptr, 2);
- nIconIndex = GET_USHORT(program_ptr, 4);
- /* FIXME is this correct ?? */
- icontype = GET_USHORT(program_ptr, 6);
- switch (icontype)
- {
- default:
- MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s, lpszGrpFile,
- IDS_WARNING, MB_OK);
- case 0x048c:
- iconXORsize = GET_USHORT(program_ptr, 8);
- iconANDsize = GET_USHORT(program_ptr, 10) / 8;
- iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12);
- iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 14);
- iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 16);
- width = GET_USHORT(iconinfo_ptr, 4);
- height = GET_USHORT(iconinfo_ptr, 6);
- planes = GET_USHORT(iconinfo_ptr, 10);
- bpp = GET_USHORT(iconinfo_ptr, 11);
- break;
- case 0x000c:
- iconANDsize = GET_USHORT(program_ptr, 8);
- iconXORsize = GET_USHORT(program_ptr, 10);
- iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12);
- iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 14);
- iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 16);
- width = GET_USHORT(iconinfo_ptr, 4);
- height = GET_USHORT(iconinfo_ptr, 6);
- planes = GET_USHORT(iconinfo_ptr, 10);
- bpp = GET_USHORT(iconinfo_ptr, 11);
- }
- if (iconANDbits_ptr + iconANDsize > buffer + size ||
- iconXORbits_ptr + iconXORsize > buffer + size) return(0);
- hIcon = CreateIcon( Globals.hInstance, width, height, planes, bpp, iconANDbits_ptr, iconXORbits_ptr );
- lpszName = buffer + GET_USHORT(program_ptr, 18);
- lpszCmdLine = buffer + GET_USHORT(program_ptr, 20);
- lpszIconFile = buffer + GET_USHORT(program_ptr, 22);
- if (iconinfo_ptr + 6 > buffer + size ||
- lpszName > buffer + size ||
- lpszCmdLine > buffer + size ||
- lpszIconFile > buffer + size) return(0);
- /* Scan Extensions */
- lpszWorkDir = "";
- nHotKey = 0;
- nCmdShow = SW_SHOWNORMAL;
- if (extension)
- {
- LPCSTR ptr = extension;
- while (ptr + 6 <= buffer + size)
- {
- UINT type = GET_USHORT(ptr, 0);
- UINT number = GET_USHORT(ptr, 2);
- UINT skip = GET_USHORT(ptr, 4);
- if (number == seqnum)
- {
- switch (type)
- {
- case 0x8000:
- if (ptr + 10 > buffer + size) return(0);
- if (ptr[6] != 'P' || ptr[7] != 'M' ||
- ptr[8] != 'C' || ptr[9] != 'C') return(0);
- break;
- case 0x8101:
- lpszWorkDir = ptr + 6;
- break;
- case 0x8102:
- if (ptr + 8 > buffer + size) return(0);
- nHotKey = GET_USHORT(ptr, 6);
- break;
- case 0x8103:
- if (ptr + 8 > buffer + size) return(0);
- nCmdShow = GET_USHORT(ptr, 6);
- break;
- default:
- MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s,
- lpszGrpFile, IDS_WARNING, MB_OK);
- }
- }
- if (!skip) break;
- ptr += skip;
- }
- }
- return (PROGRAM_AddProgram(hGroup, hIcon, lpszName, x, y,
- lpszCmdLine, lpszIconFile,
- nIconIndex, lpszWorkDir,
- nHotKey, nCmdShow));
- }
- /***********************************************************************
- *
- * GRPFILE_WriteGroupFile
- */
- BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup)
- {
- CHAR szPath[MAX_PATHNAME_LEN];
- PROGGROUP *group = LocalLock(hGroup);
- OFSTRUCT dummy;
- HFILE file;
- BOOL ret;
- GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
- MAX_PATHNAME_LEN,
- group->bFileNameModified);
- /* Try not to overwrite original files */
- /* group->bOverwriteFileOk == TRUE only if a file has the modified format */
- if (!group->bOverwriteFileOk &&
- OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
- {
- /* Original file exists, try `.gr' extension */
- GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
- MAX_PATHNAME_LEN, TRUE);
- if (OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
- {
- /* File exists. Do not overwrite */
- MAIN_MessageBoxIDS_s(IDS_FILE_NOT_OVERWRITTEN_s, szPath,
- IDS_INFO, MB_OK);
- return FALSE;
- }
- /* Inform about the modified file name */
- if (IDCANCEL ==
- MAIN_MessageBoxIDS_s(IDS_SAVE_GROUP_AS_s, szPath, IDS_INFO,
- MB_OKCANCEL | MB_ICONINFORMATION))
- return FALSE;
- }
- {
- /* Warn about the (possible) incompatibility */
- CHAR msg[MAX_PATHNAME_LEN + 200];
- wsprintfA(msg,
- "Group files written by this DRAFT Program Manager "
- "possibly cannot be read by the Microsoft Program Manager!!\n"
- "Are you sure to write %s?", szPath);
- if (IDOK != MessageBoxA(Globals.hMainWnd, msg, "WARNING",
- MB_OKCANCEL | MB_DEFBUTTON2)) return FALSE;
- }
- /* Open file */
- file = _lcreat(szPath, 0);
- if (file != HFILE_ERROR)
- {
- ret = GRPFILE_DoWriteGroupFile(file, group);
- _lclose(file);
- }
- else ret = FALSE;
- if (!ret)
- MAIN_MessageBoxIDS_s(IDS_FILE_WRITE_ERROR_s, szPath, IDS_ERROR, MB_OK);
- return(ret);
- }
- /***********************************************************************
- *
- * GRPFILE_CalculateSizes
- */
- static VOID GRPFILE_CalculateSizes(PROGRAM *program, INT *Progs, INT *Icons,
- UINT *sizeAnd, UINT *sizeXor)
- {
- ICONINFO info;
- BITMAP bmp;
- GetIconInfo( program->hIcon, &info );
- GetObjectW( info.hbmMask, sizeof(bmp), &bmp );
- *sizeAnd = bmp.bmHeight * ((bmp.bmWidth + 15) / 16 * 2);
- GetObjectW( info.hbmColor, sizeof(bmp), &bmp );
- *sizeXor = bmp.bmHeight * bmp.bmWidthBytes;
- DeleteObject( info.hbmMask );
- DeleteObject( info.hbmColor );
- *Progs += 24;
- *Progs += strlen(LocalLock(program->hName)) + 1;
- *Progs += strlen(LocalLock(program->hCmdLine)) + 1;
- *Progs += strlen(LocalLock(program->hIconFile)) + 1;
- *Icons += 12; /* IconInfo */
- *Icons += *sizeAnd;
- *Icons += *sizeXor;
- }
- /***********************************************************************/
- UINT16 GRPFILE_checksum;
- BOOL GRPFILE_checksum_half_word;
- BYTE GRPFILE_checksum_last_byte;
- /***********************************************************************
- *
- * GRPFILE_InitChecksum
- */
- static void GRPFILE_InitChecksum(void)
- {
- GRPFILE_checksum = 0;
- GRPFILE_checksum_half_word = 0;
- }
- /***********************************************************************
- *
- * GRPFILE_GetChecksum
- */
- static UINT16 GRPFILE_GetChecksum(void)
- {
- return GRPFILE_checksum;
- }
- /***********************************************************************
- *
- * GRPFILE_WriteWithChecksum
- *
- * Looks crazier than it is:
- *
- * chksum = 0;
- * chksum = cksum - 1. word;
- * chksum = cksum - 2. word;
- * ...
- *
- * if (filelen is even)
- * great I'm finished
- * else
- * ignore last byte
- */
- static UINT GRPFILE_WriteWithChecksum(HFILE file, LPCSTR str, UINT size)
- {
- UINT i;
- if (GRPFILE_checksum_half_word) {
- GRPFILE_checksum -= GRPFILE_checksum_last_byte;
- }
- for (i=0; i < size; i++) {
- if (GRPFILE_checksum_half_word) {
- GRPFILE_checksum -= str[i] << 8;
- } else {
- GRPFILE_checksum -= str[i];
- }
- GRPFILE_checksum_half_word ^= 1;
- }
- if (GRPFILE_checksum_half_word) {
- GRPFILE_checksum_last_byte = str[size-1];
- GRPFILE_checksum += GRPFILE_checksum_last_byte;
- }
- return _lwrite(file, str, size);
- }
- /***********************************************************************
- *
- * GRPFILE_DoWriteGroupFile
- */
- static BOOL GRPFILE_DoWriteGroupFile(HFILE file, PROGGROUP *group)
- {
- CHAR buffer[34];
- HLOCAL hProgram;
- INT NumProg, Title, Progs, Icons, Extension;
- INT CurrProg, CurrIcon, nCmdShow, ptr, seqnum;
- UINT sizeAnd, sizeXor;
- BOOL need_extension;
- LPCSTR lpszTitle = LocalLock(group->hName);
- UINT16 checksum;
- GRPFILE_InitChecksum();
- /* Calculate offsets */
- NumProg = 0;
- Icons = 0;
- Extension = 0;
- need_extension = FALSE;
- hProgram = group->hPrograms;
- while(hProgram)
- {
- PROGRAM *program = LocalLock(hProgram);
- LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
- NumProg++;
- GRPFILE_CalculateSizes(program, &Icons, &Extension, &sizeAnd, &sizeXor);
- /* Set a flag if an extension is needed */
- if (lpszWorkDir[0] || program->nHotKey ||
- program->nCmdShow != SW_SHOWNORMAL) need_extension = TRUE;
- hProgram = program->hNext;
- }
- Title = 34 + NumProg * 2;
- Progs = Title + strlen(lpszTitle) + 1;
- Icons += Progs;
- Extension += Icons;
- /* Header */
- buffer[0] = 'P';
- buffer[1] = 'M';
- buffer[2] = 'C';
- buffer[3] = 'C';
- PUT_SHORT(buffer, 4, 0); /* Checksum zero for now, written later */
- PUT_SHORT(buffer, 6, Extension);
- /* Update group->nCmdShow */
- if (IsIconic(group->hWnd)) nCmdShow = SW_SHOWMINIMIZED;
- else if (IsZoomed(group->hWnd)) nCmdShow = SW_SHOWMAXIMIZED;
- else nCmdShow = SW_SHOWNORMAL;
- PUT_SHORT(buffer, 8, nCmdShow);
- PUT_SHORT(buffer, 10, group->x);
- PUT_SHORT(buffer, 12, group->y);
- PUT_SHORT(buffer, 14, group->width);
- PUT_SHORT(buffer, 16, group->height);
- PUT_SHORT(buffer, 18, group->iconx);
- PUT_SHORT(buffer, 20, group->icony);
- PUT_SHORT(buffer, 22, Title);
- PUT_SHORT(buffer, 24, 0x0020); /* unknown */
- PUT_SHORT(buffer, 26, 0x0020); /* unknown */
- PUT_SHORT(buffer, 28, 0x0108); /* unknown */
- PUT_SHORT(buffer, 30, 0x0000); /* unknown */
- PUT_SHORT(buffer, 32, NumProg);
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 34)) return FALSE;
- /* Program table */
- CurrProg = Progs;
- CurrIcon = Icons;
- hProgram = group->hPrograms;
- while(hProgram)
- {
- PROGRAM *program = LocalLock(hProgram);
- PUT_SHORT(buffer, 0, CurrProg);
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 2))
- return FALSE;
- GRPFILE_CalculateSizes(program, &CurrProg, &CurrIcon, &sizeAnd, &sizeXor);
- hProgram = program->hNext;
- }
- /* Title */
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, lpszTitle, strlen(lpszTitle) + 1))
- return FALSE;
- /* Program entries */
- CurrProg = Progs;
- CurrIcon = Icons;
- hProgram = group->hPrograms;
- while(hProgram)
- {
- PROGRAM *program = LocalLock(hProgram);
- LPCSTR Name = LocalLock(program->hName);
- LPCSTR CmdLine = LocalLock(program->hCmdLine);
- LPCSTR IconFile = LocalLock(program->hIconFile);
- INT next_prog = CurrProg;
- INT next_icon = CurrIcon;
- GRPFILE_CalculateSizes(program, &next_prog, &next_icon, &sizeAnd, &sizeXor);
- PUT_SHORT(buffer, 0, program->x);
- PUT_SHORT(buffer, 2, program->y);
- PUT_SHORT(buffer, 4, program->nIconIndex);
- PUT_SHORT(buffer, 6, 0x048c); /* unknown */
- PUT_SHORT(buffer, 8, sizeXor);
- PUT_SHORT(buffer, 10, sizeAnd * 8);
- PUT_SHORT(buffer, 12, CurrIcon);
- PUT_SHORT(buffer, 14, CurrIcon + 12 + sizeAnd);
- PUT_SHORT(buffer, 16, CurrIcon + 12);
- ptr = CurrProg + 24;
- PUT_SHORT(buffer, 18, ptr);
- ptr += strlen(Name) + 1;
- PUT_SHORT(buffer, 20, ptr);
- ptr += strlen(CmdLine) + 1;
- PUT_SHORT(buffer, 22, ptr);
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 24) ||
- (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, Name, strlen(Name) + 1) ||
- (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, CmdLine, strlen(CmdLine) + 1) ||
- (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, IconFile, strlen(IconFile) + 1))
- return FALSE;
- CurrProg = next_prog;
- CurrIcon = next_icon;
- hProgram = program->hNext;
- }
- /* Icons */
- #if 0 /* FIXME: this is broken anyway */
- hProgram = group->hPrograms;
- while(hProgram)
- {
- PROGRAM *program = LocalLock(hProgram);
- CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
- LPVOID XorBits, AndBits;
- INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
- INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
- /* DumpIcon16(LocalLock(program->hIcon), 0, &XorBits, &AndBits);*/
- PUT_SHORT(buffer, 0, iconinfo->ptHotSpot.x);
- PUT_SHORT(buffer, 2, iconinfo->ptHotSpot.y);
- PUT_SHORT(buffer, 4, iconinfo->nWidth);
- PUT_SHORT(buffer, 6, iconinfo->nHeight);
- PUT_SHORT(buffer, 8, iconinfo->nWidthBytes);
- buffer[10] = iconinfo->bPlanes;
- buffer[11] = iconinfo->bBitsPerPixel;
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 12) ||
- (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, AndBits, sizeAnd) ||
- (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, XorBits, sizeXor)) return FALSE;
- hProgram = program->hNext;
- }
- #endif
- if (need_extension)
- {
- /* write `PMCC' extension */
- PUT_SHORT(buffer, 0, 0x8000);
- PUT_SHORT(buffer, 2, 0xffff);
- PUT_SHORT(buffer, 4, 0x000a);
- buffer[6] = 'P'; buffer[7] = 'M';
- buffer[8] = 'C'; buffer[9] = 'C';
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 10))
- return FALSE;
- seqnum = 0;
- hProgram = group->hPrograms;
- while(hProgram)
- {
- PROGRAM *program = LocalLock(hProgram);
- LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
- /* Working directory */
- if (lpszWorkDir[0])
- {
- PUT_SHORT(buffer, 0, 0x8101);
- PUT_SHORT(buffer, 2, seqnum);
- PUT_SHORT(buffer, 4, 7 + strlen(lpszWorkDir));
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 6) ||
- (UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, lpszWorkDir, strlen(lpszWorkDir) + 1))
- return FALSE;
- }
- /* Hot key */
- if (program->nHotKey)
- {
- PUT_SHORT(buffer, 0, 0x8102);
- PUT_SHORT(buffer, 2, seqnum);
- PUT_SHORT(buffer, 4, 8);
- PUT_SHORT(buffer, 6, program->nHotKey);
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 8)) return FALSE;
- }
- /* Show command */
- if (program->nCmdShow)
- {
- PUT_SHORT(buffer, 0, 0x8103);
- PUT_SHORT(buffer, 2, seqnum);
- PUT_SHORT(buffer, 4, 8);
- PUT_SHORT(buffer, 6, program->nCmdShow);
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 8)) return FALSE;
- }
- seqnum++;
- hProgram = program->hNext;
- }
- /* Write `End' extension */
- PUT_SHORT(buffer, 0, 0xffff);
- PUT_SHORT(buffer, 2, 0xffff);
- PUT_SHORT(buffer, 4, 0x0000);
- if ((UINT)HFILE_ERROR == GRPFILE_WriteWithChecksum(file, buffer, 6)) return FALSE;
- }
- checksum = GRPFILE_GetChecksum();
- _llseek(file, 4, SEEK_SET);
- PUT_SHORT(buffer, 0, checksum);
- _lwrite(file, buffer, 2);
- return TRUE;
- }
|