windows-nt/Source/XPSP1/NT/shell/osshell/progman/convgrp.c
2020-09-26 16:20:57 +08:00

338 lines
11 KiB
C

/****************************************************************************/
/* */
/* CONVGRP.C - */
/* */
/* Conversion from Windows NT 1.0 program group format with ANSI */
/* strings to Windows NT 1.0a group format with UNICODE strings. */
/* */
/* Created: 09-10-93 Johanne Caron */
/* */
/****************************************************************************/
#include "progman.h"
#include "convgrp.h"
/*--------------------------------------------------------------------------*/
/* */
/* CreateNewGroupFromAnsiGroup() - */
/* */
/* This function creates a new, empty group. */
/* */
/*--------------------------------------------------------------------------*/
HANDLE CreateNewGroupFromAnsiGroup(LPGROUPDEF_A lpGroupORI)
{
HANDLE hT = NULL;
LPGROUPDEF lpgd;
int i;
int cb;
int cItems; // number of items in 16bit group
LPSTR pGroupName; // 32bit group name
LPTSTR pGroupNameUNI = NULL; // 32bit UNICODE group name
INT wGroupNameLen; // length of pGroupName DWORD aligned.
INT cchWideChar = 0; //character count of resultant unicode string
INT cchMultiByte = 0;
pGroupName = (LPSTR)PTR(lpGroupORI, lpGroupORI->pName);
//
// convert pGroupName to unicode here
//
cchMultiByte=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pGroupName, -1, pGroupNameUNI, cchWideChar);
pGroupNameUNI = LocalAlloc(LPTR,(++cchMultiByte)*sizeof(TCHAR));
if (pGroupNameUNI)
{
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED, pGroupName, -1, pGroupNameUNI, cchMultiByte);
wGroupNameLen = MyDwordAlign(sizeof(TCHAR)*(lstrlen(pGroupNameUNI) + 1));
cItems = lpGroupORI->cItems;
cb = sizeof(GROUPDEF) + (cItems * sizeof(DWORD)) + wGroupNameLen;
//
// In CreateNewGroup before GlobalAlloc.
//
hT = GlobalAlloc(GHND, (DWORD)cb);
if (hT)
{
lpgd = (LPGROUPDEF)GlobalLock(hT);
//
// use the NT 1.0 group settings for what we can.
//
lpgd->nCmdShow = lpGroupORI->nCmdShow;
lpgd->wIconFormat = lpGroupORI->wIconFormat;
lpgd->cxIcon = lpGroupORI->cxIcon;
lpgd->cyIcon = lpGroupORI->cyIcon;
lpgd->ptMin.x = (INT)lpGroupORI->ptMin.x;
lpgd->ptMin.y = (INT)lpGroupORI->ptMin.y;
CopyRect(&(lpgd->rcNormal),&(lpGroupORI->rcNormal));
lpgd->dwMagic = GROUP_UNICODE;
lpgd->cbGroup = (DWORD)cb;
lpgd->pName = sizeof(GROUPDEF) + cItems * sizeof(DWORD);
lpgd->Reserved1 = (WORD)-1;
lpgd->Reserved2 = (DWORD)-1;
lpgd->cItems = (WORD)cItems;
for (i = 0; i < cItems; i++)
{
lpgd->rgiItems[i] = 0;
}
lstrcpy((LPTSTR)((LPSTR)lpgd + sizeof(GROUPDEF) + cItems * sizeof(DWORD)),
pGroupNameUNI); // lhb tracks
LocalFree(pGroupNameUNI);
GlobalUnlock(hT);
}
}
return hT;
}
DWORD AddThing_A(HANDLE hGroup, LPSTR lpStuff, WORD cbStuff)
{
LPTSTR lpStuffUNI = NULL;
BOOL bAlloc = FALSE;
DWORD cb;
if (cbStuff == 0xFFFF) {
return 0xFFFF;
}
if (!cbStuff) {
INT cchMultiByte;
INT cchWideChar = 0;
bAlloc = TRUE;
cchMultiByte=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpStuff,
-1,lpStuffUNI,cchWideChar) ;
lpStuffUNI = LocalAlloc(LPTR,(++cchMultiByte)*sizeof(TCHAR)) ;
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpStuff,
-1,lpStuffUNI,cchMultiByte) ;
cbStuff = (WORD)sizeof(TCHAR)*(1 + lstrlen(lpStuffUNI)); // lhb tracks
} else {
lpStuffUNI = (LPTSTR)lpStuff;
}
cb = AddThing(hGroup, lpStuffUNI, cbStuff);
if (bAlloc)
LocalFree(lpStuffUNI);
return(cb);
}
/*--------------------------------------------------------------------------*/
/* */
/* ConvertToUnicodeGroup() - */
/* */
/* returns the size of the new unicode group. */
/* */
/*--------------------------------------------------------------------------*/
int ConvertToUnicodeGroup(LPGROUPDEF_A lpGroupORI, LPHANDLE lphNewGroup)
{
HANDLE hNewGroup;
LPGROUPDEF lpgd;
LPITEMDEF lpid;
LPBYTE lpid_A;
LPPMTAG lptag_A;
LPSTR lpTagValue;
WORD wTagId;
LPSTR lpT;
DWORD offset;
int cb;
int i;
INT cchMultiByte;
INT cchWideChar;
LPTSTR lpTagValueUNI;
BOOL bAlloc = FALSE;
hNewGroup = CreateNewGroupFromAnsiGroup(lpGroupORI);
if (!hNewGroup) {
return(0);
}
//
// Add all items to the new formatted group.
//
for (i = 0; (i < (int)lpGroupORI->cItems) && (i < CITEMSMAX); i++) {
//
// Get the pointer to the 16bit item
//
lpid_A = (LPBYTE)ITEM(lpGroupORI, i);
if (lpGroupORI->rgiItems[i]) {
//
// Create the item.
//
offset = AddThing(hNewGroup, NULL, sizeof(ITEMDEF));
if (!offset) {
KdPrint(("ConvGrp: Addthing ITEMDEF failed for item %d \n", i));
goto QuitThis;
}
lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
lpgd->rgiItems[i] = offset;
lpid = ITEM(lpgd, i);
//
// Set the item's position.
//
lpid->pt.x = ((LPITEMDEF_A)lpid_A)->pt.x;
lpid->pt.y = ((LPITEMDEF_A)lpid_A)->pt.y;
//
// Add the item's Name.
//
GlobalUnlock(hNewGroup);
lpT = (LPSTR)PTR(lpGroupORI,((LPITEMDEF_A)lpid_A)->pName);
offset = AddThing_A(hNewGroup, lpT, 0);
if (!offset) {
KdPrint(("ConvGrp: Addthing pName failed for item %d \n", i));
goto PuntCreation;
}
lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
lpid = ITEM(lpgd, i);
lpid->pName = offset;
//
// Add the item's Command line.
//
GlobalUnlock(hNewGroup);
lpT = (LPSTR)PTR(lpGroupORI, ((LPITEMDEF_A)lpid_A)->pCommand);
offset = AddThing_A(hNewGroup, lpT, 0);
if (!offset) {
KdPrint(("ConvGrp: Addthing pCommand failed for item %d \n", i));
goto PuntCreation;
}
lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
lpid = ITEM(lpgd, i);
lpid->pCommand = offset;
//
// Add the item's Icon path.
//
GlobalUnlock(hNewGroup);
lpT = (LPSTR)PTR(lpGroupORI, ((LPITEMDEF_A)lpid_A)->pIconPath);
offset = AddThing_A(hNewGroup, lpT, 0);
if (!offset) {
KdPrint(("ConvGrp: Addthing pIconPath failed for item %d \n", i));
goto PuntCreation;
}
lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
lpid = ITEM(lpgd, i);
lpid->pIconPath = offset;
//
// Get the item's icon resource using the Icon path and the icon index.
// And add the item's Icon resource.
//
lpid->iIcon = ((LPITEMDEF_A)lpid_A)->idIcon;
lpid->cbIconRes = ((LPITEMDEF_A)lpid_A)->cbIconRes;
lpid->wIconVer = ((LPITEMDEF_A)lpid_A)->wIconVer;
GlobalUnlock(hNewGroup);
lpT = (LPBYTE)PTR(lpGroupORI, ((LPITEMDEF_A)lpid_A)->pIconRes);
offset = AddThing_A(hNewGroup, (LPSTR)lpT, lpid->cbIconRes);
if (!offset) {
KdPrint(("ConvGrp: AddThing pIconRes failed for item %d \n", i));
goto PuntCreation;
}
lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
lpid = ITEM(lpgd, i);
lpid->pIconRes = offset;
GlobalUnlock(hNewGroup);
}
}
/*
* Copy all the tags to the new group format.
*/
lptag_A = (LPPMTAG)((LPSTR)lpGroupORI + lpGroupORI->cbGroup); // lhb tracks
if (lptag_A->wID == ID_MAGIC &&
lptag_A->wItem == (int)0xFFFF &&
*(LONG FAR *)lptag_A->rgb == PMTAG_MAGIC) {
//
// This is the first tag id, goto start of item tags.
//
(LPBYTE)lptag_A += lptag_A->cb;
while (lptag_A->wID != ID_LASTTAG) {
wTagId = lptag_A->wID;
cb = lptag_A->cb - (3 * sizeof(DWORD)); // cb - sizeof tag
if (wTagId == ID_MINIMIZE) {
lpTagValueUNI = NULL;
}
else {
lpTagValue = lptag_A->rgb ;
if (wTagId != ID_HOTKEY) {
bAlloc = TRUE;
cchWideChar = 0;
cchMultiByte=MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED,lpTagValue,
-1,lpTagValueUNI,cchWideChar) ;
lpTagValueUNI = LocalAlloc(LPTR,(++cchMultiByte)*sizeof(TCHAR)) ;
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpTagValue,
-1,lpTagValueUNI,cchMultiByte) ;
cb = sizeof(TCHAR)*(lstrlen(lpTagValueUNI) + 1); // lhb tracks
}
else {
lpTagValueUNI = (LPTSTR)lpTagValue;
}
}
if (! AddTag( hNewGroup,
lptag_A->wItem, // wItem
wTagId, // wID
lpTagValueUNI, // rgb : tag value
cb
)) {
KdPrint(("ConvGrp: AddTag wItem=%d, wID=%d failed \n",
lptag_A->wItem ,
lptag_A->wID));
}
if (bAlloc && lpTagValueUNI) {
LocalFree(lpTagValueUNI);
bAlloc = FALSE;
}
(LPBYTE)lptag_A += lptag_A->cb ; // go to next tag
}
}
lpgd = GlobalLock(hNewGroup);
cb = SizeofGroup(lpgd);
GlobalUnlock(hNewGroup);
*lphNewGroup = hNewGroup;
return(cb);
PuntCreation:
QuitThis:
if (hNewGroup) {
GlobalFree(hNewGroup);
}
return(0);
}