/*++ 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 #include #include #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_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 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(*pcTitlesszTitle; i=0; while((i++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(*pcTitlesszTitle; while(*ptr_Cf_Text++ != '"'); i=0; while((i++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++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;ibmiColors[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;ibmciColors[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