diff options
Diffstat (limited to 'private/os2/client/dllpmnt1.c')
-rw-r--r-- | private/os2/client/dllpmnt1.c | 2224 |
1 files changed, 2224 insertions, 0 deletions
diff --git a/private/os2/client/dllpmnt1.c b/private/os2/client/dllpmnt1.c new file mode 100644 index 000000000..b560f5591 --- /dev/null +++ b/private/os2/client/dllpmnt1.c @@ -0,0 +1,2224 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + dllpmnt1.c + +Abstract: + + This module contains various calls needed internally for PM/NT + These calls implement the following API's: + (all API's deal with groups and programs) + WinCreateGroup + WinAddProgram + WinChangeProgram + WinQueryProgramTitles + WinQueryDefinition + WinDestroyGroup + WinRemoveProgram + PrfCreateGroup + PrfAddProgram + PrfChangeProgram + PrfQueryProgramTitles + PrfQueryDefinition + PrfQueryProgramHandle + PrfDestroyGroup + PrfRemoveProgram + +Implementation: + PM makes profiling in order to manage groups and programs. + PMNT do not use a profile. Instead it connect PROGMAN (program manager) + in order to execute commands or request data. + The connection is done using the DDEML package: + where service=PROGMAN, topic=PROGMAN. + It is important to notice that when creaing or removing + programs, the respective group must be active, since there is + no parameter for the group. + + OS2 uses handles, while NT uses groups' and programs' names. + An atom table implements the interface. + We couldn't use the Win32 API's of atoms because they lacked + the ability to rename an atom. + + +Author: + + Lior Moshaiov (LiorM) 9-June-1993 + +Revision History: + + Added Clipboard Module (LiorM) 10-Nov-1993 + + This module contains various calls needed internally for PM/NT + These calls implement the interface between PM & WIN32 clipboards: + (all API's deal with clipboard) + WinOpenClipbrd + WinEmptyClipbrd + WinCloseClipbrd + WinSetClipbrdData (text & bitmap) + WinQueryClipbrdData (text & bitmap) + WinQueryClipbrdFmtInfo (text & bitmap) + +--*/ + +#if PMNT /* If not for PMNT build, yield just an empty file */ + +// We need here both Win32 & Os2ss include files. +// Since they interfere, the needed definitions of os2ss & pm +// were inserted by hand. + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include "ddeml.h" +#include "os2tile.h" +#include "os2nt.h" + +#include "os2crt.h" + +//The following definitions should be compatible with ntrtl.h + +PVOID +NTAPI +RtlAllocateHeap( + IN PVOID HeapHandle, + IN ULONG Flags, + IN ULONG Size + ); +BOOLEAN +NTAPI +RtlFreeHeap( + IN PVOID HeapHandle, + IN ULONG Flags, + IN PVOID BaseAddress + ); +//The following definitions should be compatible with os2dll.h + +#define CANONICALIZE_FILE_OR_DEV 0x00000001 +typedef struct _STRING { + USHORT Length; + USHORT MaximumLength; +#ifdef MIDL_PASS + [size_is(MaximumLength), length_is(Length) ] +#endif // MIDL_PASS + PCHAR Buffer; +} STRING; +typedef STRING *PSTRING; + +#define APIRET ULONG +APIRET +Od2Canonicalize( + IN PSZ Path, + IN ULONG ExpectedType, + OUT PSTRING OutputString, + OUT PHANDLE OutputDirectory OPTIONAL, + OUT PULONG ParseFlags OPTIONAL, + OUT PULONG FileType OPTIONAL + ); + +VOID +Od2ProbeForWrite( + IN PVOID Address, + IN ULONG Length, + IN ULONG Alignment + ); + +typedef unsigned short SEL; +typedef SEL *PSEL; +#define APIRET ULONG +typedef HANDLE HSEM, *PHSEM; +APIRET +DosFreeSeg( + SEL Sel); +APIRET +DosAllocSeg( + IN USHORT cbSize, + OUT PSEL pSel, + IN USHORT fsAlloc); + +APIRET +DosAllocHuge( + IN ULONG cSegs, + IN USHORT cbPartialSeg, + OUT PSEL pSel, + IN ULONG cMaxSegs, + IN USHORT fsAlloc + ); + +APIRET +DosSemClear( + IN HSEM hsem + ); + +APIRET +DosSemSet( + IN HSEM hsem + ); + +APIRET +DosSemWait( + IN HSEM hsem, + IN LONG lTimeOut + ); + + +#pragma pack (1) +//The following definitions should be compatible with +// pmnt\tiger\src\h\pmwin.h + +typedef struct _SWP { /* swp */ + USHORT fs; + SHORT cy; + SHORT cx; + SHORT y; + SHORT x; + HWND hwndInsertBehind; + HWND hwnd; +} SWP; +typedef SWP FAR *PSWP; + +#define CFI_SELECTOR 0x0100 +#define CFI_HANDLE 0x0200 + + +//The following definitions should be compatible with +// pmnt\tiger\src\h\pmshl.h + +#define MAXNAMEL 60 + +/* window size structure */ +typedef struct _XYWINSIZE { /* xywin */ + SHORT x; + SHORT y; + SHORT cx; + SHORT cy; + USHORT fsWindow; +} XYWINSIZE; +typedef XYWINSIZE FAR *PXYWINSIZE; + +/* Definitions for fsWindow */ +#define XYF_NOAUTOCLOSE 0x0008 +#define XYF_MINIMIZED 0x0004 /* D23914 */ +#define XYF_MAXIMIZED 0x0002 /* D23914 */ +#define XYF_INVISIBLE 0x0001 +#define XYF_NORMAL 0X0000 + +/* program handle */ +typedef void far *LHANDLE; /* hprog */ +typedef LHANDLE HPROGRAM; /* hprog */ + +/* maximum path length */ +#define MAXPATHL 128 + +/* root group handle */ +#define SGH_ROOT (HPROGRAM) -1L + +typedef struct _HPROGARRAY { /* hpga */ + HPROGRAM ahprog[1]; +} HPROGARRAY; +typedef HPROGARRAY FAR *PHPROGARRAY; + +typedef CHAR PROGCATEGORY; /* progc */ +typedef PROGCATEGORY FAR *PPROGCATEGORY; + +/* values acceptable for PROGCATEGORY for PM groups */ +#define PROG_DEFAULT (PROGCATEGORY)0 +#define PROG_FULLSCREEN (PROGCATEGORY)1 +#define PROG_WINDOWABLEVIO (PROGCATEGORY)2 +#define PROG_PM (PROGCATEGORY)3 +#define PROG_GROUP (PROGCATEGORY)5 +#define PROG_REAL (PROGCATEGORY)4 /* was 7 */ +#define PROG_DLL (PROGCATEGORY)6 +#define PROG_RESERVED (PROGCATEGORY)255 + +/* visibility flag for PROGTYPE structure */ +#define SHE_VISIBLE (BYTE)0x00 +#define SHE_INVISIBLE (BYTE)0x01 +#define SHE_RESERVED (BYTE)0xFF + +typedef struct _PROGTYPE { /* progt */ + PROGCATEGORY progc; + UCHAR fbVisible; +} PROGTYPE; +typedef PROGTYPE FAR *PPROGTYPE; + +#pragma pack (1) +typedef struct _PROGRAMENTRY { /* proge */ + HPROGRAM hprog; + PROGTYPE progt; + CHAR szTitle[MAXNAMEL+1]; +} PROGRAMENTRY; +typedef PROGRAMENTRY FAR *PPROGRAMENTRY; + + +typedef struct _PIBSTRUCT { /* pib */ + PROGTYPE progt; + CHAR szTitle[MAXNAMEL+1]; + CHAR szIconFileName[MAXPATHL+1]; + CHAR szExecutable[MAXPATHL+1]; + CHAR szStartupDir[MAXPATHL+1]; + XYWINSIZE xywinInitial; + USHORT res1; + LHANDLE res2; + USHORT cchEnvironmentVars; + PCH pchEnvironmentVars; + USHORT cchProgramParameter; + PCH pchProgramParameter; +} PIBSTRUCT; +typedef PIBSTRUCT FAR *PPIBSTRUCT; + +/******************************************************************************/ +/* */ +/* Structures associated with 'Prf' calls */ +/* */ +/******************************************************************************/ + +typedef struct _PROGDETAILS { /* progde */ + ULONG Length; /* set this to sizeof(PROGDETAILS) */ + PROGTYPE progt; + USHORT pad1[3]; /* ready for 32-bit PROGTYPE */ + PSZ pszTitle; /* any of the pointers can be NULL */ + PSZ pszExecutable; + PSZ pszParameters; + PSZ pszStartupDir; + PSZ pszIcon; + PSZ pszEnvironment; /* this is terminated by /0/0 */ + SWP swpInitial; /* this replaces XYWINSIZE */ + USHORT pad2[5]; /* ready for 32-bit SWP */ +} PROGDETAILS; + +typedef PROGDETAILS FAR *PPROGDETAILS; + +typedef struct _PROGTITLE { /* progti */ + HPROGRAM hprog; + PROGTYPE progt; + USHORT pad1[3]; /* padding ready for 32-bit PROGTYPE */ + PSZ pszTitle; +} PROGTITLE; +typedef PROGTITLE FAR *PPROGTITLE; + +#pragma pack () + +extern PVOID Od2Heap; +#define MAXNAME (MAXNAMEL+1) + +// Atoms: There are atom tables of 256 entries each. +// the 1st entry points to the next table. +// all tables are allocated dynamically when needed. +// each handle (32 bits) consists of 2 atoms(16 bits): +// the most significant is the group atom (0 for the desktop), +// and the least is the atom of the program. +// the most significant byte of each atom is the table no. (1->255) +// the least significant is the index in the table (1->255) +// + +#define PMNT_TABLE_POWER 8 +#define PMNT_ATOMS_IN_TABLE (2<<(PMNT_TABLE_POWER-1)) +#define PMNT_HANDLE_TO_ATOM(a) ((a) & 0x0000ffff) +#define PMNT_TABLE_OF_ATOM(a) (USHORT)(((a)>>PMNT_TABLE_POWER) & 0x000000ff) +#define PMNT_INDEX_OF_ATOM(a) (USHORT)((a) & 0x000000ff) +#define PMNT_INDEX_TO_ATOM(a,b) ((((a)<<PMNT_TABLE_POWER)|b) & 0x0000ffff) +#define PMNT_ATOM_TO_HANDLE(a,b) (ULONG) (((a)<<(2*PMNT_TABLE_POWER)) | ((b) & 0x0000ffff)) + +static USHORT pmnt_no_of_atom_tables = 0; +static USHORT pmnt_atoms_in_last_table = 0; +static char **pmnt_1st_atom_table=NULL; +static char **pmnt_last_atom_table=NULL; + + +PCHAR +PMNTGetAtomEntry(ULONG hprog) +{ + + USHORT table_no,index,i; + ULONG atom; + char **table; + + atom = PMNT_HANDLE_TO_ATOM(hprog); + table_no = PMNT_TABLE_OF_ATOM (atom); + index= PMNT_INDEX_OF_ATOM (atom); + + if (table_no > pmnt_no_of_atom_tables) + return(NULL); + + if (table_no == pmnt_no_of_atom_tables && index > pmnt_atoms_in_last_table) + return(NULL); + + if (!(table = pmnt_1st_atom_table)) + return(NULL); + + for (i=1;i<table_no;i++) { + if (!(table = (char **) table[0])) + return(NULL); + } + return (table[index]); + +} + + + +ULONG +PMNTGetAtomName(ULONG hprog, char *szName, ULONG maxsize) +{ + + ULONG len; + char *ptr_src,*ptr_dst; + + + if (!(ptr_src = PMNTGetAtomEntry(hprog))) { + return(0L); + } + ptr_dst = szName; + len=0; + while((len<maxsize)&&(*ptr_dst++ = *ptr_src++)) len++; + return(len); + +} + + +BOOL +PMNTRenameAtom(ULONG hprog, char *szNewName) +{ + + char *ptr_src,*ptr_dst; + + + if (!(ptr_dst = PMNTGetAtomEntry(hprog))) { + return(FALSE); + } + RtlFreeHeap(Od2Heap, 0, ptr_dst); + ptr_dst = RtlAllocateHeap(Od2Heap, 0, (int) (strlen(szNewName)+1)); + ptr_src = szNewName; + while(*ptr_dst++ = *ptr_src++); + return(TRUE); + +} + + + +ULONG +PMNTExistAtom(char *szName) +{ + char **table; + USHORT i,j,no_entries; + + if (!pmnt_no_of_atom_tables) { + return(0L); + } + if (!(table = pmnt_1st_atom_table)) + return(0L); + + no_entries = PMNT_ATOMS_IN_TABLE-1; + for (i=1;i<=pmnt_no_of_atom_tables;i++) { + if (i == pmnt_no_of_atom_tables) + no_entries = pmnt_atoms_in_last_table; + for(j=1;j<=no_entries;j++) { + if (!strncmp (szName,table[j],MAXNAME)) { + return(PMNT_INDEX_TO_ATOM(i,j)); + } + } + if (i<pmnt_no_of_atom_tables) { + if (!(table = (char **) table[0])) + return(0L); + } + } + return(0L); +} + + +ULONG +PMNTAddAtom(ULONG hParent,char *szName) +{ + char *buf; + ULONG atom; + char **table; + + + + + if (!(atom = PMNTExistAtom(szName))) { + //should be added + if (!pmnt_atoms_in_last_table || + (pmnt_atoms_in_last_table == PMNT_ATOMS_IN_TABLE-1)) { + // a new table should be created + if(!(table = + RtlAllocateHeap(Od2Heap, 0, PMNT_ATOMS_IN_TABLE *sizeof(char *)))){ + return(0L); + } + if (pmnt_no_of_atom_tables == 0) { + pmnt_last_atom_table = pmnt_1st_atom_table = table; + } + else { + pmnt_last_atom_table[0] = (void *) table; + pmnt_last_atom_table = table; + } + pmnt_no_of_atom_tables++; + pmnt_atoms_in_last_table = 0; + } + pmnt_atoms_in_last_table++; + if (! (pmnt_last_atom_table[pmnt_atoms_in_last_table]=buf= + RtlAllocateHeap(Od2Heap, 0, (int) (strlen(szName)+1)))){ + return(0L); + } + strcpy(buf,szName); + atom = PMNT_INDEX_TO_ATOM(pmnt_no_of_atom_tables,pmnt_atoms_in_last_table); + } + return(PMNT_ATOM_TO_HANDLE(hParent,atom)); +} + +// These functions retrieve strings from text in CF_TEXT format. +// The format is : +// each line ends with a CR & LF (0x0d, 0x0a) +// the thex ends with the NULL char ('\0') +// 1. information about progman: +// each line consists of group name. +// 2. information about a group +// 1st line contains information about the group +// All the other lines contain information about programs in the group +// (a line for each program) +// "proram_name","command",startup_directory,icon_path,xPosition,yPosition,icon_index,Hotkey,Minimize +// + + +BOOL +PMNTGetNextStart( + PCHAR *ptr_src) +{ + char *p1,*p2,*p3; + + p1 = strchr (*ptr_src,(int)0x0d); + p2 = strchr (*ptr_src,','); + if (p2 && p2<p1) { + *ptr_src = ++p2; + p2 = strchr (*ptr_src,','); + p3 = strchr (*ptr_src,'"'); + if (p3 && p3<p1 && ( !p2 || p3<p2)) { + *ptr_src = ++p3; + return(TRUE); + } + } + return(FALSE); +} + +ULONG +PMNTGetThisString( + PCHAR *ptr_src, char *buffer, ULONG maxbuf) +{ + char *ptr_Cf_Text,*ptr_buf; + ULONG i = 0; + + ptr_Cf_Text = *ptr_src; + if (maxbuf) { + ptr_buf = buffer; + while((i<maxbuf) && (*ptr_buf++ = *ptr_Cf_Text++) != '"') i++; + *--ptr_buf = '\0'; + } + else { + while(*ptr_Cf_Text++ != '"') i++; + } + *ptr_src = ptr_Cf_Text; + return(i); +} + +ULONG +PMNTGetThisString1( + PCHAR *ptr_src, char *buffer, ULONG maxbuf, ULONG *param) +{ + char *ptr_Cf_Text,*ptr_buf; + ULONG i = 0; + + ptr_Cf_Text = *ptr_src; + if (maxbuf) { + ptr_buf = buffer; + while((i<maxbuf) && (*ptr_buf = *ptr_Cf_Text) != '"' && (*ptr_buf != ' ')) { + i++; + ptr_buf++; + ptr_Cf_Text++; + } + *ptr_buf = '\0'; + } + else { + while(*ptr_Cf_Text != '"' && *ptr_Cf_Text != ' ') { + ptr_Cf_Text++; + i++; + } + } + if (*param = (*ptr_Cf_Text++ == ' ')) + while (*ptr_Cf_Text == ' ') *ptr_Cf_Text++; + *ptr_src = ptr_Cf_Text; + return(i); +} + + +ULONG +PMNTGetNextString( + PCHAR *ptr_src, char *buffer, ULONG maxbuf) +{ + + if (!PMNTGetNextStart(ptr_src)) { + return(0L); + } + return(PMNTGetThisString(ptr_src,buffer,maxbuf)); +} + +ULONG +PMNTGetNextString1( + PCHAR *ptr_src, char *buffer, ULONG maxbuf, ULONG *param) +{ + + if (!PMNTGetNextStart(ptr_src)) { + return(0L); + } + return(PMNTGetThisString1(ptr_src,buffer,maxbuf,param)); +} + +ULONG +PMNTGetNextString0( + PCHAR *ptr_src, char *buffer, ULONG maxbuf) +{ + char *ptr_Cf_Text,*ptr_buf; + ULONG i=0; + + char *p1,*p2; + + ptr_Cf_Text = *ptr_src; + p1 = strchr (ptr_Cf_Text,(int)0x0d); + p2 = strchr (ptr_Cf_Text,','); + if (p2 && p2<p1) + ptr_Cf_Text = ++p2; + else + return(0L); + + if (maxbuf) { + ptr_buf = buffer; + while((i<maxbuf) && (*ptr_buf++ = *ptr_Cf_Text++) != ',') i++; + *--ptr_buf = '\0'; + } + else { + while(*ptr_Cf_Text++ != ',') i++; + } + *ptr_src = ptr_Cf_Text; + return(i); +} + + +#define MYMAXBUF 512 + +// retrieves canonicalized name of file from file name & starting directory + +ULONG +PMNTGetFullPath( + char *file_name, char *st_dir, PSTRING canonic_name) +{ + LPCSTR *ptr; + ULONG len=0,FileFlags,FileType; + char buf[MYMAXBUF],path_name[MYMAXBUF]; + short change_dir; + + if (change_dir = (st_dir && *st_dir)) { + GetCurrentDirectory((DWORD)MYMAXBUF,(LPSTR)buf); + SetCurrentDirectory((LPSTR) st_dir); + } + + do { + len = (ULONG) + SearchPath((LPCSTR) NULL,(LPCSTR) file_name, (LPCSTR) ".EXE", (DWORD) MYMAXBUF, + (LPSTR) path_name, (LPSTR *) &ptr); + if (!len || len > MYMAXBUF) { + KdPrint(("PMNTGetFullPath : SearchPath failed\n")); + len = 0; + break; + } + if (Od2Canonicalize(path_name,CANONICALIZE_FILE_OR_DEV,canonic_name,NULL, + &FileFlags,&FileType)) { + len = 0; + break; + } + + } while (FALSE); + if (change_dir) { + SetCurrentDirectory((LPSTR) buf); + } + return(len); + + +} + + +// The following functions are a layer between the API's and DDEML +// They are called after a connection with progman has been settled +// and they get strings (instead of handles) as input +// This layer is needed since some API's call the same DdeClientTransaction + +#define DDE_TIME_OUT 120000L // 2 minutes timeout + +BOOL +PMNTCreateGrp ( + HCONV hConv, char *GroupName) +{ + char buffer[256]; + HDDEDATA rc; + + strcpy (buffer,"[CreateGroup("); + strcat (buffer,GroupName); + strcat (buffer,",0)]"); + rc = DdeClientTransaction((LPBYTE)buffer,strlen(buffer)+1,hConv,0L,0, + XTYP_EXECUTE,DDE_TIME_OUT,NULL); + if (!rc) { + KdPrint(("PMNTCreateGrp : transaction failed\n")); + return(FALSE); + } + DdeFreeDataHandle(rc); + return(TRUE); +} + + +BOOL +PMNTAddItem( + HCONV hConv,PCHAR szTitle,PCHAR szExecutable,PCHAR szStartupDir,PCHAR szParameters) +{ + + + char buffer[256]; + HDDEDATA rc; + char *ptr; + + strcpy (buffer,"[AddItem("); + strcat (buffer,szExecutable); + if (szParameters && *szParameters) { + ptr = buffer + strlen(buffer); + *ptr++ = ' '; + strcpy(ptr,szParameters); + } + strcat (buffer,","); + strcat (buffer,szTitle); + strcat (buffer,",,,,,"); + if (szStartupDir) { + strcat (buffer,szStartupDir); + } + strcat (buffer,")]"); + rc = DdeClientTransaction((LPBYTE)buffer,strlen(buffer)+1,hConv,0L,0, + XTYP_EXECUTE,DDE_TIME_OUT,NULL); + if (!rc) { + KdPrint(("PMNTAddItem: transaction failed\n")); + return(FALSE); + } + DdeFreeDataHandle(rc); + return(TRUE); + +} + + +BOOL +PMNTDeleteItem ( + HCONV hConv, ULONG del_rep, char *szName) +{ + char buffer[256]; + HDDEDATA rc; + + + if (del_rep == 0) + strcpy (buffer,"[DeleteItem("); + else + strcpy (buffer,"[ReplaceItem("); + strcat (buffer,szName); + strcat (buffer,")]"); + rc = DdeClientTransaction((LPBYTE)buffer,strlen(buffer)+1,hConv,0L,0, + XTYP_EXECUTE,DDE_TIME_OUT,NULL); + if (!rc) { + KdPrint(("PMNTDeleteItem: transaction failed\n")); + return(FALSE); + } + DdeFreeDataHandle(rc); + return(TRUE); +} + +BOOL +PMNTGetGrpText( + DWORD idInst, HCONV hConv, char *szName, HDDEDATA *phData, PCHAR *ptr_Cf_Text) +{ + + DWORD cbData; + HSZ hszItem; + + + hszItem = DdeCreateStringHandle(idInst,szName,0); + *phData = DdeClientTransaction((LPBYTE)NULL,0,hConv,hszItem,CF_TEXT, + XTYP_REQUEST,DDE_TIME_OUT,NULL); + DdeFreeStringHandle(idInst,hszItem); + if (!(*phData)) { + KdPrint(("PMNTGetGrpText: transaction failed\n")); + return(FALSE); + } + if (!(*ptr_Cf_Text=DdeAccessData(*phData,&cbData))) { + KdPrint(("PMNTGetGrpText: access data failed\n")); + DdeFreeDataHandle(*phData); + return(FALSE); + } + return(TRUE); + +} + + + +BOOL +PMNTGetGroupText( + DWORD idInst, HCONV hConv, LONG hGroup, HDDEDATA *phData, PCHAR *ptr_Cf_Text) +{ + + char szGroupName[MAXNAME]; + + if (hGroup == (LONG) SGH_ROOT) { + strcpy(szGroupName,"PROGMAN"); + } + else + if (!(PMNTGetAtomName(hGroup,szGroupName,MAXNAME))) { + KdPrint(("PMNTGetGroupText: PMNTGetAtomName failed\n")); + return(FALSE); + } + + if (!PMNTGetGrpText(idInst,hConv,szGroupName,phData,ptr_Cf_Text)) { + return(FALSE); + } + + return(TRUE); + +} + +ULONG +PMNTChangePrg( + DWORD idInst, HCONV hConv, char *szGroup, char *szOldProg, + char *szNewProg,char *szExecutable,char *szStartupDir,char *szParameters) +{ + char *buffer,*ptr_c,*ptr_buf,*ptr_Cf_Text,szBuf[MAXNAME]; + HDDEDATA hData,rc; + ULONG len; + short sucsess=FALSE; + short rtl_alloc=FALSE; + + + + do { + if (!PMNTGetGrpText(idInst,hConv,szGroup,&hData,&ptr_Cf_Text)) { + return(FALSE); + } + if (!ptr_Cf_Text || !(*ptr_Cf_Text)) { + break; + } + + // activate group + if (!PMNTCreateGrp(hConv,szGroup)) { + break; + } + + // each line ends with CR LF, + // format is "name","command",startup dir,iconPath,xPos,yPos,iconindex,hotkey,minimize0x0d 0x0a + // 1st line consist the group name + // The order of parameters in AddItem is different + // "command","name",iconPath,iconIndex,xPos,yPos,startup dir,hotkey,minimize + while(*ptr_Cf_Text++ != 0x0a); //1st line + + while (*ptr_Cf_Text) { + while (*ptr_Cf_Text++ != '"'); + PMNTGetThisString(&ptr_Cf_Text,szBuf,MAXNAME); + if (!strncmp (szBuf,szOldProg,MAXNAME)) { + len = 10; + len+=strlen(szNewProg)+3; + len+=strlen(szExecutable)+3; + if (szParameters) + len+=strlen(szParameters)+1; + if (szStartupDir) { + len+=strlen(szStartupDir)+1; + } + else { + len++; + } + while (*ptr_Cf_Text++ != ','); + while (*ptr_Cf_Text++ != ','); + while (*ptr_Cf_Text++ != ','); + ptr_c = ptr_Cf_Text; + while (*ptr_c++ != 0x0d) len++; + len+=3; + buffer = RtlAllocateHeap(Od2Heap, 0, len); + rtl_alloc = TRUE; + strcpy(buffer,"[AddItem("); + strcat (buffer,szExecutable); + if (szParameters && *szParameters) { + ptr_buf = buffer + strlen(buffer); + *ptr_buf++ = ' '; + strcpy(ptr_buf,szParameters); + } + strcat (buffer,","); + strcat (buffer,szNewProg); + strcat (buffer,","); + ptr_buf = buffer + strlen(buffer); + // keep IconPath + while((*ptr_buf++ = *ptr_Cf_Text++) != ','); + // keep Icon Index + ptr_c = ptr_Cf_Text; + while(*ptr_c++ != ','); + while(*ptr_c++ != ','); + while((*ptr_buf++ = *ptr_c++) != ','); + // keep xPos,yPos + while((*ptr_buf++ = *ptr_Cf_Text++) != ','); + while((*ptr_buf++ = *ptr_Cf_Text++) != ','); + if (szStartupDir) { + strcpy(ptr_buf,szStartupDir); + } + ptr_buf += strlen(ptr_buf); + *ptr_buf++ = ','; + // keep HotKey, Minimize + ptr_Cf_Text = ptr_c; + while((*ptr_buf++ = *ptr_Cf_Text++) != 0x0d); + ptr_buf--; + strcpy(ptr_buf,")]"); + if (!(PMNTDeleteItem(hConv,1L,szOldProg))) { + break; + } + //Add an Item + if (!(rc = DdeClientTransaction((LPBYTE)buffer,strlen(buffer)+1,hConv,0L,0, + XTYP_EXECUTE,DDE_TIME_OUT,NULL))) { + KdPrint(("PMNTChangePrg :transaction failed\n")); + break; + } + DdeFreeDataHandle(rc); + sucsess = TRUE; + break; + } + while (*ptr_Cf_Text++ != 0x0a); + } + + } while (FALSE); + + if (rtl_alloc) RtlFreeHeap(Od2Heap, 0, buffer); + DdeFreeDataHandle(hData); + return(sucsess); +} + + + +BOOL +PMNTChangeGrp( + DWORD idInst, HCONV hConv, char *szOldGroup, char *szNewGroup) +{ + char *buffer,*ptr_c,*ptr_buf,*ptr_Cf_Text,*ptr_xp; + HDDEDATA hData,rc; + ULONG len,maxbuf; + short sucsess=FALSE; + short rtl_alloc = FALSE; + + + do { + if (!PMNTGetGrpText(idInst,hConv,szOldGroup,&hData,&ptr_Cf_Text)) { + return(FALSE); + } + if (!ptr_Cf_Text || !(*ptr_Cf_Text)) { + break; + } + + // create new group + if (!PMNTCreateGrp(hConv,szNewGroup)) { + break; + } + + while(*ptr_Cf_Text++ != 0x0a); //1st line + ptr_c = ptr_Cf_Text; + maxbuf = 0; + while (*ptr_c) { + len = 0; + while (*ptr_c++ != 0x0a) len++; + if (len>maxbuf) maxbuf=len; + } + maxbuf+=12; + buffer = RtlAllocateHeap(Od2Heap, 0, maxbuf); + rtl_alloc= TRUE; + strcpy(buffer,"[AddItem("); + + while (*ptr_Cf_Text) { + ptr_c = ptr_Cf_Text; + ptr_buf = buffer+9; + //copy cmd (2nd item) + while (*ptr_c++ != ','); + while ((*ptr_buf++ = *ptr_c++) != ','); + //copy name (1st item) + while ((*ptr_buf++ = *ptr_Cf_Text++) != ','); + ptr_Cf_Text = ptr_c; //both on end of 2nd item + //copy IconPath (4th item) + while (*ptr_c++ != ','); + while ((*ptr_buf++ = *ptr_c++) != ','); + ptr_xp = ptr_c; //start of xPosition + //copy IconIndex (7th item) + while (*ptr_c++ != ','); + while (*ptr_c++ != ','); + while ((*ptr_buf++ = *ptr_c++) != ','); + //copy xy position + while ((*ptr_buf++ = *ptr_xp++) != ','); + while ((*ptr_buf++ = *ptr_xp++) != ','); + //copy start directory + while ((*ptr_buf++ = *ptr_Cf_Text++) != ','); + //copy HotKey + while ((*ptr_buf++ = *ptr_c++) != ','); + //copy Minimize flag + while ((*ptr_buf++ = *ptr_c++) != 0x0d); + --ptr_buf; + ptr_Cf_Text = ptr_c; + while(*ptr_Cf_Text++ != 0x0a); //1st line + strcpy(ptr_buf,")]"); + //Add an Item + if (!(rc = DdeClientTransaction((LPBYTE)buffer,strlen(buffer)+1,hConv,0L,0, + XTYP_EXECUTE,DDE_TIME_OUT,NULL))) { + KdPrint(("PMNTChangeGrp :transaction of add item failed\n")); + break; + } + DdeFreeDataHandle(rc); + + ptr_Cf_Text = ptr_c; + while (*ptr_Cf_Text++ != 0x0a); + } + + strcpy (buffer,"[DeleteGroup("); + strcat (buffer,szOldGroup); + strcat (buffer,",0)]"); + if (!(rc = DdeClientTransaction((LPBYTE)buffer,strlen(buffer)+1,hConv,0L,0, + XTYP_EXECUTE,DDE_TIME_OUT,NULL))) { + KdPrint(("PMNTChangeGrp :transaction of delete group failed\n")); + break; + } + sucsess = TRUE; + DdeFreeDataHandle(rc); + } while (FALSE); + + if (rtl_alloc) RtlFreeHeap(Od2Heap, 0, buffer); + DdeFreeDataHandle(hData); + return(sucsess); +} + + +ULONG +PMNTWinQueryProgramTitles ( + char *ptr_Cf_Text, LONG hGroup, PPROGRAMENTRY paproge, ULONG cbBuf, PULONG pcTitles) + +{ + PPROGRAMENTRY ptr_proge; + char *ptr_Title; + ULONG entries; + USHORT i; + + + entries = cbBuf / sizeof(PPROGRAMENTRY); + if (!entries) { + // request only the no. of programs + while(*ptr_Cf_Text) + if (*ptr_Cf_Text++ == 0x0a) (*pcTitles)++; + if (hGroup != (LONG) SGH_ROOT) (*pcTitles)--; + } + + else if (hGroup == (LONG) SGH_ROOT) { + // each line ends with CR LF, and consists of a group name + while(*pcTitles<entries) { + if (!(*ptr_Cf_Text)) break; + ptr_proge = &paproge[*pcTitles]; + ptr_Title = ptr_proge->szTitle; + i=0; + while((i++<MAXNAME) && (*ptr_Title++ = *ptr_Cf_Text++) != 0x0d); + *--ptr_Title = '\0'; + ptr_proge->hprog= + (HPROGRAM)PMNTAddAtom(0L,ptr_proge->szTitle); + ptr_proge->progt.progc=PROG_GROUP; + ptr_proge->progt.fbVisible=SHE_VISIBLE; + (*pcTitles)++; + ptr_Cf_Text++; + } + } + else { + // each line ends with CR LF, + // a program name in " " is in the beginning of each line + // followed by other parameters + // 1st line consist the group name + if (*ptr_Cf_Text) { + while(*ptr_Cf_Text++ != 0x0a); //1st line + while(*pcTitles<entries) { + if (!(*ptr_Cf_Text)) break; + ptr_proge = &paproge[*pcTitles]; + ptr_Title = ptr_proge->szTitle; + while(*ptr_Cf_Text++ != '"'); + i=0; + while((i++<MAXNAME) && ((*ptr_Title++=*ptr_Cf_Text++) != '"')); + *--ptr_Title = '\0'; + ptr_proge->hprog= + (HPROGRAM)PMNTAddAtom((ULONG)hGroup,ptr_proge->szTitle); + ptr_proge->progt.progc=PROG_DEFAULT; + ptr_proge->progt.fbVisible=SHE_VISIBLE; + (*pcTitles)++; + while(*ptr_Cf_Text++ != 0x0a); + } + } + } + return(1L); +} + +ULONG +PMNTPrfQueryProgramTitles ( + char *start_Cf_Text, LONG hGroup, PPROGTITLE paprogti, ULONG cbBuf, PULONG pcTitles) + +{ + PPROGTITLE ptr_progti; + char *ptr_Title; + ULONG Length,i,uTitles; + char *ptr_Cf_Text,*st_Title; + + + *pcTitles=0; + Length=i=0; + ptr_Cf_Text = start_Cf_Text; + + + //calculate no. of items, and needed length + if (hGroup== (LONG) SGH_ROOT) { + // each line ends with CR LF, + while (*ptr_Cf_Text) { + while(*ptr_Cf_Text++ != 0x0d) i++; + (*pcTitles)++; + ptr_Cf_Text++; + } + } + else { + + // each line ends with CR LF, + // a program name in " " is in the beginning of each line + // followed by other parameters + // 1st line consist the group name + if (*ptr_Cf_Text) { + while(*ptr_Cf_Text++ != 0x0a); //1st line + while (*ptr_Cf_Text) { + while(*ptr_Cf_Text++ != '"'); + while(*ptr_Cf_Text++ != '"') i++; + (*pcTitles)++; + while(*ptr_Cf_Text++ != 0x0a); + } + } + } + Length = ((ULONG)(sizeof(PROGTITLE)+1) * (*pcTitles)) + i; + + if (cbBuf) { + //the contents should be copied + if (Length > cbBuf) { + return(0L); + } + ptr_Title = (char *) &paprogti[*pcTitles]; + ptr_Cf_Text = start_Cf_Text; + uTitles= 0; + + if (hGroup == (LONG) SGH_ROOT) { + // each line ends with CR LF, and consists of a group name + + while (*ptr_Cf_Text) { + st_Title = ptr_Title; + ptr_progti = &paprogti[uTitles++]; + ptr_progti->pszTitle = (void *) FLATTOFARPTR(st_Title); + while((*ptr_Title++ = *ptr_Cf_Text++) != 0x0d); + *(ptr_Title-1) = '\0'; + ptr_progti->hprog= + (HPROGRAM)PMNTAddAtom(0L,st_Title); + ptr_progti->progt.progc=PROG_GROUP; + ptr_progti->progt.fbVisible=SHE_VISIBLE; + ptr_Cf_Text++; + } + } + else { + // each line ends with CR LF, + // a program name in " " is in the beginning of each line + // followed by other parameters + // 1st line consist the group name + if (*ptr_Cf_Text) { + while(*ptr_Cf_Text++ != 0x0a); //1st line + while (*ptr_Cf_Text) { + st_Title = ptr_Title; + ptr_progti = &paprogti[uTitles++]; + ptr_progti->pszTitle = (void *) FLATTOFARPTR(st_Title); + while(*ptr_Cf_Text++ != '"'); + while((*ptr_Title++=*ptr_Cf_Text++) != '"'); + *(ptr_Title-1) = '\0'; + ptr_progti->hprog= + (HPROGRAM)PMNTAddAtom((ULONG)hGroup,st_Title); + ptr_progti->progt.progc=PROG_DEFAULT; + ptr_progti->progt.fbVisible=SHE_VISIBLE; + while(*ptr_Cf_Text++ != 0x0a); + } + } + } + } + return(Length); +} + +ULONG +PMNTWinQueryDefinition ( + char *ptr_Cf_Text, char *szName, PPIBSTRUCT ppib, ULONG cbBuf) + +{ + char szBuf[MAXNAME],*ptr_buf,*ptr_par; + ULONG Length = sizeof(PIBSTRUCT),len,maxbuf,param; + + + + if (cbBuf) { + memset((char *)ppib,(int) 0,cbBuf); + ppib->progt.fbVisible=SHE_VISIBLE; + ppib->progt.progc= (ptr_Cf_Text) ? PROG_DEFAULT : PROG_GROUP; + strcpy(ppib->szTitle,szName); + } + + + if (ptr_Cf_Text) { + //if it is a program (and not a group)we should query other parameters + // each line ends with CR LF, + // format is "name","command",startup dir,iconPath,xPos,yPos,iconindex,hotkey,minimize0x0d 0x0a + // 1st line consist the group name + while(*ptr_Cf_Text++ != 0x0a); //1st line + while (*ptr_Cf_Text) { + while (*ptr_Cf_Text++ != '"'); + PMNTGetThisString(&ptr_Cf_Text,szBuf,MAXNAME); + if (!strncmp (szBuf,szName,MAXNAME)) { + if (cbBuf) { + ptr_buf = ppib->szExecutable; + maxbuf = MAXPATHL+1; + ptr_par = (char *)ppib+Length; + ppib->pchProgramParameter = (void *) FLATTOFARPTR(ptr_par); + } + else { + ptr_buf = NULL; + maxbuf = 0; + } + Length++; + len = PMNTGetNextString1(&ptr_Cf_Text,ptr_buf,maxbuf,¶m); + if (cbBuf) ptr_buf = ptr_par; + if (len && param) { + len = PMNTGetThisString(&ptr_Cf_Text,ptr_buf,maxbuf); + } + else + len = 0; + if (cbBuf) ppib->cchProgramParameter = (USHORT)(len+1); + Length += len; + + if (cbBuf) { + PMNTGetNextString0(&ptr_Cf_Text,ppib->szStartupDir,maxbuf); + } + break; + } + } + } + return(Length+2); +} + + +ULONG +PMNTPrfQueryDefinition ( + char *ptr_Cf_Text, char *szName, PPROGDETAILS pprogde, ULONG cbBuf) + +{ + char szBuf[MAXNAME],*ptr_st,*ptr_buf; + ULONG Length = sizeof(PROGDETAILS),len,maxbuf,param; + + + + if (cbBuf) { + ptr_st = (char *) pprogde; + memset(ptr_st,(int) 0,cbBuf); + pprogde->Length = Length; + pprogde->progt.fbVisible=SHE_VISIBLE; + pprogde->progt.progc= (ptr_Cf_Text) ? PROG_DEFAULT : PROG_GROUP; + ptr_buf = ptr_st + Length; + pprogde->pszTitle= (void *) FLATTOFARPTR (ptr_buf); + strcpy(ptr_buf,szName); + } + Length += strlen(szName)+1; + + + + if (ptr_Cf_Text) { + //if it is a program (and not a group)we should query other parameters + // each line ends with CR LF, + // format is "name","command",startup dir,iconPath,xPos,yPos,iconindex,hotkey,minimize0x0d 0x0a + // 1st line consist the group name + while(*ptr_Cf_Text++ != 0x0a); //1st line + while (*ptr_Cf_Text) { + while (*ptr_Cf_Text++ != '"'); + PMNTGetThisString(&ptr_Cf_Text,szBuf,MAXNAME); + if (!strncmp (szBuf,szName,MAXNAME)) { + if (cbBuf) { + ptr_buf = ptr_st+Length; + pprogde->pszExecutable = (void *) FLATTOFARPTR(ptr_buf); + maxbuf = MAXPATHL+1; + } + else { + ptr_buf = NULL; + maxbuf = 0; + } + len = PMNTGetNextString1(&ptr_Cf_Text,ptr_buf,maxbuf,¶m); + Length+= len+1; + if (cbBuf) { + ptr_buf = ptr_st+Length; + pprogde->pszParameters= (void *) FLATTOFARPTR(ptr_buf); + } + if (len && param) { + len = PMNTGetThisString(&ptr_Cf_Text,ptr_buf,maxbuf); + } + else + len = 0; + Length += len+1; + + if (cbBuf) { + ptr_buf = ptr_st+Length; + pprogde->pszStartupDir= (void *) FLATTOFARPTR(ptr_buf); + + } + len = PMNTGetNextString0(&ptr_Cf_Text,ptr_buf,maxbuf); + Length+=len+1; + if (cbBuf) { + ptr_buf = ptr_st+Length; + pprogde->pszIcon=(void *) FLATTOFARPTR(ptr_buf); + } + Length++; + break; + } + } + } + return(Length); +} + +// This function establishes the connection with progman + +BOOL +PMNTDdeConnect( + DWORD *pidInst, HCONV *phConv) +{ + HSZ hszService,hszTopic; + + *pidInst = 0L; + if (DdeInitialize (pidInst,NULL, + APPCLASS_STANDARD|APPCMD_CLIENTONLY, 0L)) { + + KdPrint(("PMNTDdeConnect : DdeInitialize failed\n")); + return(FALSE); + } + + hszService = DdeCreateStringHandle(*pidInst,"PROGMAN",0); + hszTopic = DdeCreateStringHandle(*pidInst,"PROGMAN",0); + *phConv = DdeConnect(*pidInst,hszService,hszTopic,NULL); + DdeFreeStringHandle(*pidInst,hszService); + DdeFreeStringHandle(*pidInst,hszTopic); + if (*phConv == (HCONV) 0) { + KdPrint(("PMNTDdeConnect : DdeConnect failed\n")); + DdeUninitialize(*pidInst); + return(FALSE); + } + return(TRUE); +} + +// The following API's are exported API's that implement PM API's. +// The naming convention is: Win___, Prf___ are implemented by PMNT___ + + +ULONG +PMNTCreateGroup( + PSZ GroupName, PULONG phGroup) +{ + + + DWORD idInst; + BOOL sucsess; + HCONV hConv; + + + *phGroup = 0L; + sucsess = FALSE; + if (!GroupName || !(*GroupName)) { + return(0L); + } + + do { + if (!PMNTDdeConnect(&idInst,&hConv)) { + return(0L); + } + if (!(PMNTCreateGrp(hConv,GroupName))) { + break; + } + sucsess = (BOOL) (*phGroup = PMNTAddAtom(0L,GroupName)); + + } while (FALSE); + + + DdeDisconnect(hConv); + DdeUninitialize(idInst); + return(sucsess); + +} + + + +ULONG +PMNTQueryProgramTitles( + ULONG win_prf, LONG hGroup, PVOID ProgTitles, ULONG cbBuf, PULONG pcTitles) +{ + + + DWORD idInst; + HCONV hConv; + HDDEDATA hData; + PCHAR ptr_Cf_Text; + ULONG Length; + + *pcTitles=0; + Length=0; + + do { + if (cbBuf) Od2ProbeForWrite(ProgTitles,1,1); + if (!PMNTDdeConnect(&idInst,&hConv)) { + return(0L); + } + if (!PMNTGetGroupText(idInst,hConv,hGroup,&hData,&ptr_Cf_Text)) { + break; + } + + if (win_prf == 0L) { + Length = PMNTWinQueryProgramTitles( + ptr_Cf_Text,hGroup,ProgTitles,cbBuf,pcTitles); + } + else { + Length = PMNTPrfQueryProgramTitles( + ptr_Cf_Text,hGroup,ProgTitles,cbBuf,pcTitles); + } + DdeFreeDataHandle(hData); + + } while (FALSE); + + + DdeDisconnect(hConv); + DdeUninitialize(idInst); + return(Length); + +} + +ULONG +PMNTQueryDefinition( + ULONG win_prf, LONG hProg, PVOID ProgDefinition, ULONG cbBuf) +{ + + + DWORD idInst; + HCONV hConv; + HDDEDATA hData; + PCHAR ptr_Cf_Text; + ULONG Length; + LONG hGroup; + char szName[MAXNAME]; + + Length=0; + hData = 0; + + do { + if (cbBuf) Od2ProbeForWrite(ProgDefinition,1,1); + if (!PMNTDdeConnect(&idInst,&hConv)) { + return(0L); + } + + if (!(PMNTGetAtomName(hProg,szName,MAXNAME))) { + KdPrint(("PMNTQueryDefinition : PMNTGetAtomName failed\n")); + break; + } + + ptr_Cf_Text = NULL; + if (hGroup = (hProg>>16)) { + if (!PMNTGetGroupText(idInst,hConv,hGroup,&hData,&ptr_Cf_Text)) { + break; + } + } + + if (win_prf == 0L) { + Length = PMNTWinQueryDefinition( + ptr_Cf_Text,szName,ProgDefinition,cbBuf); + } + else { + Length = PMNTPrfQueryDefinition( + ptr_Cf_Text,szName,ProgDefinition,cbBuf); + } + + if (hData) DdeFreeDataHandle(hData); + } while (FALSE); + + + DdeDisconnect(hConv); + DdeUninitialize(idInst); + return(Length); + +} + + +ULONG +PMNTQueryProgramHandle( + PCHAR PathNameOS2, PHPROGARRAY phpga, ULONG cb, PULONG pcHandles) +{ + + + DWORD idInst; + HCONV hConv; + HDDEDATA hDataG,hDataP; + ULONG Length; + + ULONG len,entries,param,hGroup,hProg,i,FileFlags,FileType; + char GroupName[MYMAXBUF]; + char ProgName[MYMAXBUF]; + char FileNameNT[MYMAXBUF]; + char StartDir[MYMAXBUF]; + STRING CanonicNameNT,CanonicNameOS2; + char *ptr_Cf_Root,*ptr_Cf_Text,*ptr_grp; + + + *pcHandles=0; + Length=0; + entries = cb / sizeof(HPROGRAM); + + do { + if (cb) Od2ProbeForWrite(phpga,1,1); + if (!PMNTDdeConnect(&idInst,&hConv)) { + return(0L); + } + if (!PMNTGetGroupText(idInst,hConv,(LONG)SGH_ROOT,&hDataG,&ptr_Cf_Root)) { + break; + } + + while(*ptr_Cf_Root) { + // get group name + ptr_grp = GroupName; + i=0; + while((i++<MYMAXBUF) && ((*ptr_grp++ = *ptr_Cf_Root++) != 0x0d)); + *--ptr_grp = '\0'; + // get group programs + if (!PMNTGetGrpText(idInst,hConv,GroupName,&hDataP,&ptr_Cf_Text)) { + break; + } + while(*ptr_Cf_Text++ != 0x0a); // skip 1st line + while (*ptr_Cf_Text) { + while (*ptr_Cf_Text++ != '"'); + PMNTGetThisString(&ptr_Cf_Text,ProgName,MYMAXBUF); + len = PMNTGetNextString1(&ptr_Cf_Text,FileNameNT,MYMAXBUF,¶m); + if (len && param) { + PMNTGetThisString(&ptr_Cf_Text,NULL,0L); + } + PMNTGetNextString0(&ptr_Cf_Text,StartDir,MYMAXBUF); + while(*ptr_Cf_Text++ != 0x0a); // goto end of line of program + if (!PMNTGetFullPath(FileNameNT,StartDir,&CanonicNameNT)) { + break; + } + if (Od2Canonicalize(PathNameOS2,CANONICALIZE_FILE_OR_DEV + ,&CanonicNameOS2,NULL,&FileFlags,&FileType)) { + RtlFreeHeap(Od2Heap, 0, CanonicNameNT.Buffer); + break; + } + strupr(CanonicNameNT.Buffer); + strupr(CanonicNameOS2.Buffer); + if (!strcmp(CanonicNameOS2.Buffer,CanonicNameNT.Buffer)) { + if (*pcHandles < entries) { + hGroup = PMNTAddAtom(0L,GroupName); + hProg = PMNTAddAtom(hGroup,ProgName); + phpga->ahprog[*pcHandles] = (HPROGRAM) hProg; + } + else if (cb) { + // buffer is not large enough + *pcHandles = 0L; + return(0L); + } + Length += sizeof(HPROGRAM); + (*pcHandles)++; + } + + RtlFreeHeap(Od2Heap, 0, CanonicNameNT.Buffer); + RtlFreeHeap(Od2Heap, 0, CanonicNameOS2.Buffer); + } + DdeFreeDataHandle(hDataP); // free data of ptr_Cf_Text + while(*ptr_Cf_Root++ != 0x0a); // goto end of line of group + } + + + + DdeFreeDataHandle(hDataG); + + } while (FALSE); + + + DdeDisconnect(hConv); + DdeUninitialize(idInst); + return(Length); + +} + + + +ULONG +PMNTAddProgram( + ULONG hGroupHandle,PCHAR szTitle,PCHAR szExecutable,PCHAR szStartupDir, + PCHAR szParameters, PULONG phProg) +{ + DWORD idInst; + char szGroupName[MAXNAME]; + short sucsess; + HCONV hConv; + + *phProg = 0L; + sucsess = FALSE; + if (!(szTitle) || !(*szTitle)) { + return(0L); + } + if (!(szExecutable) || !(*szExecutable)) { + return(0L); + } + + do { + if (!PMNTDdeConnect(&idInst,&hConv)) { + return(0L); + } + + if (!(PMNTGetAtomName(hGroupHandle,szGroupName,MAXNAME))) { + break; + } + if (!(PMNTCreateGrp(hConv,szGroupName))) { + break; + } + if (!(PMNTAddItem(hConv,szTitle,szExecutable,szStartupDir,szParameters))) { + break; + } + sucsess = (BOOL) (*phProg = PMNTAddAtom(hGroupHandle,szTitle)); + + } while (FALSE); + + + DdeDisconnect(hConv); + DdeUninitialize(idInst); + return(sucsess); + +} + + + +ULONG +PMNTChangeProgram( + ULONG hProg,PCHAR szTitle,PCHAR szExecutable,PCHAR szStartupDir, + PCHAR szParameters) +{ + DWORD idInst; + char szParentName[MAXNAME]; + char szName[MAXNAME]; + short sucsess,changed_name; + ULONG hParent; + HCONV hConv; + HDDEDATA hData = 0; + + + sucsess = FALSE; + if (!(szTitle) || !(*szTitle)) { + return(0L); + } + if (hParent = (hProg>>16)) { + if (!(szExecutable) || !(*szExecutable)) { + return(0L); + } + } + + do { + if (!PMNTDdeConnect(&idInst,&hConv)) { + return(0L); + } + + if (!(PMNTGetAtomName(hProg,szName,MAXNAME))) { + break; + } + changed_name = strncmp(szName,szTitle,MAXNAME); + if (hParent) { + // should change a program item + // make its group active + PMNTGetAtomName(hParent,szParentName,MAXNAME); + if (!PMNTChangePrg(idInst,hConv,szParentName,szName + ,szTitle,szExecutable,szStartupDir,szParameters)) { + break; + } + } + else { + // should change a group , the only thing we should care about is its name + if (changed_name) { + if (!PMNTChangeGrp(idInst,hConv,szName,szTitle)) { + break; + } + } + } + if (changed_name) { + PMNTRenameAtom(hProg,szTitle); + } + sucsess = TRUE; + + } while (FALSE); + + + DdeDisconnect(hConv); + DdeUninitialize(idInst); + return(sucsess); + +} + + +BOOL +PMNTDestroyGroup( + LONG hGroupHandle) +{ + + + DWORD idInst; + char buffer[256]; + char szGroupName[MAXNAME]; + short sucsess; + HCONV hConv; + HDDEDATA rc; + + + sucsess = FALSE; + + do { + if (!PMNTDdeConnect(&idInst,&hConv)) { + return(FALSE); + } + + PMNTGetAtomName(hGroupHandle,szGroupName,MAXNAME); + + strcpy (buffer,"[DeleteGroup("); + strcat (buffer,szGroupName); + strcat (buffer,",0)]"); + rc = DdeClientTransaction((LPBYTE)buffer,strlen(buffer)+1,hConv,0L,0, + XTYP_EXECUTE,DDE_TIME_OUT,NULL); + + if (!rc) { + KdPrint(("PMNTDestroyGroup : transaction failed\n")); + break; + } + DdeFreeDataHandle(rc); + sucsess = TRUE; + + } while (FALSE); + + + DdeDisconnect(hConv); + DdeUninitialize(idInst); + return(sucsess); + +} + + + +BOOL +PMNTRemoveProgram( + LONG hProg) +{ + + + DWORD idInst; + char szName[MAXNAME]; + short sucsess; + HCONV hConv; + ULONG hGroup; + + + sucsess = FALSE; + + do { + if (!PMNTDdeConnect(&idInst,&hConv)) { + return(FALSE); + } + + hGroup = (hProg>>16); + + PMNTGetAtomName(hGroup,szName,MAXNAME); + + if (!(PMNTCreateGrp(hConv,szName))) { + break; + } + + PMNTGetAtomName(hProg,szName,MAXNAME); + + if (!(PMNTDeleteItem(hConv,0L,szName))) { + break; + } + + sucsess = TRUE; + + } while (FALSE); + + + DdeDisconnect(hConv); + DdeUninitialize(idInst); + return(sucsess); + +} + +/*****************************************/ +/* PM <-> WIN32 CLIPBOARD implementation */ +/*****************************************/ + +#define PMNT_CF_TEXT 1 +#define PMNT_CF_BITMAP 2 + +SEL QuerySel=0; + +ULONG +PMNTOpenClipbrd( + IN HWND hwnd) +{ + return((ULONG) OpenClipboard(hwnd)); +} + + +ULONG +PMNTCloseClipbrd( + ) +{ + if (QuerySel) + { + DosFreeSeg(QuerySel); + QuerySel=0; + } + return((ULONG) CloseClipboard()); +} + + +ULONG +PMNTEmptyClipbrd( + ) +{ + return ((ULONG) EmptyClipboard()); +} + + +ULONG +PMNTSetClipbrdText( + IN ULONG ulData) +{ + HANDLE handle; + char *ptrData,*ptrCopy; + DWORD cb; + SEL sel; + + if (ulData) { + sel = (SEL) ulData; + ptrData = SELTOFLAT(sel); + cb = strlen(ptrData) + 1; + if (!(handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,cb))) { + return((ULONG) FALSE); + } + if (!(ptrCopy = GlobalLock(handle))) { + return((ULONG) FALSE); + } + while(*ptrCopy++=*ptrData++); + GlobalUnlock(handle); + } + else { + handle=NULL; + } + + return ((SetClipboardData(CF_TEXT,handle)) ? (ULONG) TRUE : (ULONG) FALSE); + +} + + +ULONG +PMNTSetClipbrdBitmap( + IN PBITMAPCOREINFO pbmiPM, IN PVOID lpbInit) +{ + HBITMAP hbitmap; + HDC hdc; + USHORT no_of_colors,i; + PBITMAPINFO pbmi; + SEL selBitmapInfo; + USHORT cbBitmapInfo; + ULONG rc = FALSE; + + + if (! pbmiPM) { + return ((SetClipboardData(CF_BITMAP,NULL)) ? (ULONG) TRUE : (ULONG) FALSE); + } + no_of_colors = (pbmiPM->bmciHeader.bcBitCount <= 8) + ? (1 << pbmiPM->bmciHeader.bcBitCount) : 0; + cbBitmapInfo = sizeof(BITMAPINFO) + (sizeof(RGBQUAD) * (no_of_colors)); + + if (DosAllocSeg (cbBitmapInfo,&selBitmapInfo,0)) { + KdPrint(("PMNTSetClipbrdBitmap(): DosAllocSeg() failed\n")); + return(FALSE); + } + + pbmi = SELTOFLAT(selBitmapInfo); + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = pbmiPM->bmciHeader.bcWidth; + pbmi->bmiHeader.biHeight = pbmiPM->bmciHeader.bcHeight; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = pbmiPM->bmciHeader.bcBitCount; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + for (i=0;i<no_of_colors;i++) { + pbmi->bmiColors[i].rgbBlue = pbmiPM->bmciColors[i].rgbtBlue; + pbmi->bmiColors[i].rgbGreen = pbmiPM->bmciColors[i].rgbtGreen; + pbmi->bmiColors[i].rgbRed = pbmiPM->bmciColors[i].rgbtRed; + pbmi->bmiColors[i].rgbReserved = 0; + } + + if (! (hdc = CreateDC("DISPLAY",NULL,NULL,NULL))) { + KdPrint(("PMNTSetClipbrdBitmap: CreateDC() faild\n")); + goto exit_set_bitmap_1; + } + if (! ( hbitmap = CreateDIBitmap(hdc,&(pbmi->bmiHeader),CBM_INIT,lpbInit,pbmi,DIB_RGB_COLORS))){ + KdPrint(("PMNTSetClipbrdBitmap: CreateDIBitmap() faild\n")); + goto exit_set_bitmap_2; + } + + rc = (SetClipboardData(CF_BITMAP,(HANDLE)hbitmap)) ? (ULONG) TRUE : (ULONG) FALSE; + +exit_set_bitmap_2: + DeleteDC(hdc); +exit_set_bitmap_1: + DosFreeSeg(selBitmapInfo); + return(rc); +} + + +void +PMNTQueryClipbrdText( + OUT PULONG pulData) +{ + HANDLE handle; + char *ptrData,*ptrCopy; + USHORT cb; + + *pulData=0; + if (!(handle = GetClipboardData(CF_TEXT))) { + return; + } + if (!(ptrData = GlobalLock(handle))) { + return; + } + cb = strlen(ptrData) + 1; + if (QuerySel) { + DosFreeSeg(QuerySel); + } + if (DosAllocSeg(cb,&QuerySel,0)) { + KdPrint(("PMNTQueryClipbrdData: cannot allocate memory\n")); + return; + } + *pulData = (ULONG) QuerySel; + if (ptrCopy = SELTOFLAT(QuerySel)) { + while(*ptrCopy++=*ptrData++); + } + GlobalUnlock(handle); + +} + + +ULONG +PMNTQueryClipbrdBitmap( + OUT PBITMAPCOREINFO *ppbmiPM, OUT PVOID *ppbBuffer) +{ + HBITMAP hbitmap; + HDC hdc; + USHORT no_of_colors,i; + BITMAPINFO bmi; + PBITMAPINFO pbmi; + SEL selBitmapInfo,selBuffer; + USHORT cbBitmapInfo; + ULONG cbBuffer; + USHORT absHeight,absWidth; + ULONG rc = (ULONG)FALSE; + + + *ppbmiPM = NULL; + *ppbBuffer = NULL; + + if (!(hbitmap = (HBITMAP) GetClipboardData(CF_BITMAP))) { + return((ULONG) FALSE); + } + if (! (hdc = CreateDC("DISPLAY",NULL,NULL,NULL))) { + KdPrint(("PMNTQueryClipbrdBitmap: CreateDC() faild\n")); + return((ULONG) FALSE); + } + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biBitCount = 0; + GetDIBits(hdc,hbitmap,0,0,NULL,&bmi,DIB_RGB_COLORS); + absHeight = abs(bmi.bmiHeader.biHeight); + absWidth = abs(bmi.bmiHeader.biWidth); + + if (bmi.bmiHeader.biHeight < 0) { + KdPrint(("PMNTQueryClipbrdBitmap: biHeight=%lx\n",bmi.bmiHeader.biHeight)); + } + if (bmi.bmiHeader.biWidth < 0) { + KdPrint(("PMNTQueryClipbrdBitmap: biWidth=%lx\n",bmi.bmiHeader.biWidth)); + } + if (bmi.bmiHeader.biPlanes != 1) { + KdPrint(("PMNTQueryClipbrdBitmap: biPlanes=%x\n",bmi.bmiHeader.biPlanes)); + bmi.bmiHeader.biPlanes=1; + } + if (bmi.bmiHeader.biCompression) { + KdPrint(("PMNTQueryClipbrdBitmap: biCompression=%lx\n",bmi.bmiHeader.biCompression)); + bmi.bmiHeader.biCompression = BI_RGB; + } + if (bmi.bmiHeader.biXPelsPerMeter) { + KdPrint(("PMNTQueryClipbrdBitmap: biXPelsPerMeter=%lx\n",bmi.bmiHeader.biXPelsPerMeter)); + bmi.bmiHeader.biXPelsPerMeter = 0; + } + if (bmi.bmiHeader.biYPelsPerMeter) { + KdPrint(("PMNTQueryClipbrdBitmap: biYPelsPerMeter=%lx\n",bmi.bmiHeader.biYPelsPerMeter)); + bmi.bmiHeader.biYPelsPerMeter = 0; + } + bmi.bmiHeader.biClrUsed = 0; + bmi.bmiHeader.biClrImportant = 0; + + if (bmi.bmiHeader.biBitCount == 16 || bmi.bmiHeader.biBitCount == 32) { + KdPrint(("PMNTQueryClipbrdBitmap: BitCount = %x\n",bmi.bmiHeader.biBitCount)); + bmi.bmiHeader.biBitCount = 24; + } + + no_of_colors = (bmi.bmiHeader.biBitCount <= 8) + ? (1 << bmi.bmiHeader.biBitCount) : 0; + cbBitmapInfo = sizeof(BITMAPINFO) + (sizeof(RGBQUAD) * (no_of_colors)); + + if (DosAllocSeg (cbBitmapInfo,&selBitmapInfo,0)) { + KdPrint(("PMNTQueryClipbrdBitmap: 1st DosAllocSeg() failed\n")); + goto exit_query_bitmap; + } + pbmi = SELTOFLAT(selBitmapInfo); + pbmi->bmiHeader = bmi.bmiHeader; + + cbBuffer = (((bmi.bmiHeader.biBitCount * absWidth) + 31)/32) + * 4 * absHeight; + if (cbBuffer <= _64K) { + if (DosAllocSeg ((USHORT)cbBuffer,&selBuffer,0)) { + KdPrint(("PMNTQueryClipbrdBitmap: 2nd DosAllocSeg() failed\n")); + goto exit_query_bitmap; + } + } + else { + if (DosAllocHuge(cbBuffer / _64K , (USHORT)(cbBuffer % _64K) , &selBuffer, 0L,0)) { + KdPrint(("PMNTQueryClipbrdBitmap: DosAllocHuge() failed\n")); + goto exit_query_bitmap; + } + } + *ppbBuffer = SELTOFLAT(selBuffer); + + + if (!(GetDIBits(hdc,hbitmap,0,absHeight,*ppbBuffer,pbmi,DIB_RGB_COLORS))){ + KdPrint(("PMNTQueryClipbrdBitmap(): 2nd GetDiBits failed\n")); + goto exit_query_bitmap; + } + + if (bmi.bmiHeader.biBitCount == 16 || bmi.bmiHeader.biBitCount == 32) { + KdPrint(("PMNTQueryClipbrdBitmap: BitCount = %x\n",bmi.bmiHeader.biBitCount)); + bmi.bmiHeader.biBitCount = 24; + } + + *ppbmiPM = (PBITMAPCOREINFO) pbmi; + + (*ppbmiPM)->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER); + (*ppbmiPM)->bmciHeader.bcWidth = absWidth; + (*ppbmiPM)->bmciHeader.bcHeight = absHeight; + (*ppbmiPM)->bmciHeader.bcPlanes = 1; + (*ppbmiPM)->bmciHeader.bcBitCount = bmi.bmiHeader.biBitCount; + + for (i=0;i<no_of_colors;i++) { + (*ppbmiPM)->bmciColors[i].rgbtBlue = pbmi->bmiColors[i].rgbBlue; + (*ppbmiPM)->bmciColors[i].rgbtGreen = pbmi->bmiColors[i].rgbGreen; + (*ppbmiPM)->bmciColors[i].rgbtRed = pbmi->bmiColors[i].rgbRed; + } + + + *ppbmiPM = (void *) FLATTOFARPTR((*ppbmiPM)); + *ppbBuffer = (void *) FLATTOFARPTR((*ppbBuffer)); + rc = (ULONG) TRUE; + +exit_query_bitmap: + DeleteDC(hdc); + return(rc); + +} + + + +ULONG +PMNTQueryClipbrdFmtInfo( + IN ULONG fmt, OUT PUSHORT pfsFmtInfo) +{ + ULONG exist_fmt; + + exist_fmt = (*pfsFmtInfo) = 0; + + if (fmt == PMNT_CF_TEXT) { + if (exist_fmt = (ULONG) IsClipboardFormatAvailable(CF_TEXT)) { + *pfsFmtInfo = CFI_SELECTOR; + } + } + else if (fmt == PMNT_CF_BITMAP) { + if (exist_fmt = (ULONG) IsClipboardFormatAvailable(CF_BITMAP)) { + *pfsFmtInfo = CFI_HANDLE; + } + } + + return(exist_fmt); +} + + + +long FAR PASCAL WndProc(HWND,UINT,WPARAM,LPARAM); +typedef struct _CLIPBRDDATA { + ULONG SemPM; + ULONG SemWin32; + ULONG hwnd; + ULONG fempty; + USHORT QueryFmt; +} CLIPBRDDATA; +typedef CLIPBRDDATA FAR *PCLIPBRDDATA; +PCLIPBRDDATA pClipbrdData=NULL; + +ULONG +PMNTWin32Clipbrd( + IN PCLIPBRDDATA ptrdata) +{ + static char szAppName[]="PMNTClipboard"; + MSG msg; + WNDCLASS wndclass; + + + pClipbrdData = ptrdata; + + wndclass.style = 0; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = NULL; + wndclass.hIcon = NULL; + wndclass.hCursor = NULL; + wndclass.hbrBackground = NULL; + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szAppName; + + RegisterClass(&wndclass); + + pClipbrdData->hwnd = (ULONG) CreateWindow(szAppName, + "", + 0, + -1, + -1, + 0, + 0, + NULL, + NULL, + NULL, + NULL); + + + while (GetMessage (&msg,(HWND) pClipbrdData->hwnd,0,0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return(msg.wParam); +} + +long FAR PASCAL WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) + +{ + HWND hOwner; + + switch (msg) { + + case WM_RENDERFORMAT: + + if ((pClipbrdData->QueryFmt = (USHORT) wParam) == CF_TEXT + || pClipbrdData->QueryFmt == CF_BITMAP) { + DosSemSet(&(pClipbrdData->SemPM)); + DosSemClear(&(pClipbrdData->SemWin32)); + DosSemWait(&(pClipbrdData->SemPM),-1L); + } + return(0); + + case WM_DESTROYCLIPBOARD: + + hOwner = GetClipboardOwner(); + if (hOwner != hwnd) { + // new owner is Win32 app, not PMNT app + pClipbrdData->fempty = TRUE; + DosSemSet(&(pClipbrdData->SemPM)); + DosSemClear(&(pClipbrdData->SemWin32)); + DosSemWait(&(pClipbrdData->SemPM),-1L); + pClipbrdData->fempty = FALSE; + } + return(0); + } + return(DefWindowProc(hwnd,msg,wParam,lParam)); +} + +#if 0 // We decided not to use the code below for now +/****************************************************************************** + * PMNTCloseRetryPopup: * + * Close the "Wait", "End Task", "Cancel" pop-up dialog opened by the Console* + * when closing a CMD window representing a PM app. * + * * + * Parameters: * + * * + * fClose: 0 - Simulate 'Cancel' * + * Otherwise, 'Wait' * + ******************************************************************************/ + +ULONG +PMNTCloseRetryPopup( + IN ULONG fClose) +{ + HWND hwndPopup, hwndParent; + HMODULE modulePopup; + HINSTANCE instancePopup; + USHORT TimeOut = 5; + + if (fClose) + fClose = IDRETRY; + else + fClose = IDCANCEL; + + hwndPopup = GetTopWindow(NULL); // Get handle of Retry popup + hwndParent = (HWND)GetWindowLong(hwndPopup, GWL_HWNDPARENT); + modulePopup = (HMODULE)GetClassLong(hwndPopup, GCL_HMODULE); + instancePopup = (HINSTANCE)GetWindowLong(hwndPopup, GWL_HINSTANCE); + // DbgPrint("Popup=%x, Parent=%x, Module=%x, instance=%x\n",hwndPopup, hwndParent, modulePopup, instancePopup); + + // The pop-up dialog is identified by 3 conditions: + // - has no parent (hwndParent is NULL) + // - modulePopup is NULL + // - instancePopup is NULL (i.e. we got the first instance of this window + // class on the screen) + // WARNING: the present code & comments should be taken with caution since + // they are based on partial knowledge and mostly experimentation. + while (((hwndParent != NULL) || (modulePopup != 0) || (instancePopup != 0)) + && TimeOut--) + { + Sleep(300L); + hwndPopup = GetTopWindow(NULL); // Get handle of Retry popup + hwndParent = (HWND)GetWindowLong(hwndPopup, GWL_HWNDPARENT); + modulePopup = (HMODULE)GetClassLong(hwndPopup, GCL_HMODULE); + instancePopup = (HINSTANCE)GetWindowLong(hwndPopup, GWL_HINSTANCE); + // DbgPrint("Popup=%x, Parent=%x, Module=%x, instance=%x\n",hwndPopup, hwndParent, modulePopup, instancePopup); + } + + PostMessage(hwndPopup, WM_COMMAND, (WPARAM)fClose, (LPARAM)0); + + return(NO_ERROR); +} +#endif //0 + +#endif // PMNT + |