mirror of https://github.com/lianthony/NT4.0
2224 lines
60 KiB
2224 lines
60 KiB
/*++
|
|
|
|
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
|
|
|