diff --git a/reactos/Makefile b/reactos/Makefile index 5bcdcc7e5bf..3d000cbefe5 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -13,7 +13,7 @@ COMPONENTS = iface_native iface_additional hallib ntoskrnl HALS = halx86 BUS = acpi isapnp DLLS = ntdll kernel32 advapi32 crtdll msvcrt fmifs gdi32 msafd \ - ole32 oleaut32 secur32 shell32 user32 ws2_32 version + user32 oleaut32 secur32 shell32 ws2_32 version SUBSYS = smss win32k csrss # diff --git a/reactos/include/errors.h b/reactos/include/errors.h index 62e40168034..fbb40233b2d 100644 --- a/reactos/include/errors.h +++ b/reactos/include/errors.h @@ -35,6 +35,18 @@ extern "C" { #endif /* __cplusplus */ +// +// Return Code macros +// +#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0) +#define FAILED(Status) ((HRESULT)(Status)<0) + +// +// Success Codes +// +#define S_OK 0x00000000L +#define S_FALSE 0x00000001L + /* Numerical order */ #define LZERROR_UNKNOWNALG (-8) @@ -713,6 +725,437 @@ extern "C" { #define ERROR_RPL_NOT_ALLOWED 4006L #define ERROR_NO_BROWSER_SERVERS_FOUND 6118L + +/* HRESULT values for OLE, SHELL and other Interface stuff */ +/* the codes 4000-40ff are reserved for OLE */ +#define NOERROR 0L + +#define E_PENDING 0x8000000AL + + +#define E_NOTIMPL 0x80004001L +#define E_NOINTERFACE 0x80004002L +#define E_POINTER 0x80004003L +#define E_ABORT 0x80004004L +#define E_FAIL 0x80004005L +/* FIXME: E_UNSPEC is not a standard value but it is used by + * FileMoniker, IOleLink and DoDragDrop as a return value. + */ +#define E_UNSPEC E_FAIL + + +#define CO_E_INIT_TLS 0x80004006L +#define CO_E_INIT_SHARED_ALLOCATOR 0x80004007L +#define CO_E_INIT_MEMORY_ALLOCATOR 0x80004008L +#define CO_E_INIT_CLASS_CACHE 0x80004009L +#define CO_E_INIT_RPC_CHANNEL 0x8000400AL +#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL 0x8000400BL +#define CO_E_INIT_TLS_CHANNEL_CONTROL 0x8000400CL +#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR 0x8000400DL +#define CO_E_INIT_SCM_MUTEX_EXISTS 0x8000400EL +#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS 0x8000400FL +#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE 0x80004010L +#define CO_E_INIT_SCM_EXEC_FAILURE 0x80004011L +#define CO_E_INIT_ONLY_SINGLE_THREADED 0x80004012L + +#define E_UNEXPECTED 0x8000FFFFL + +#define RPC_E_CALL_REJECTED 0x80010001L +#define RPC_E_CALL_CANCELED 0x80010002L +#define RPC_E_CANTPOST_INSENDCALL 0x80010003L +#define RPC_E_CANTCALLOUT_INASYNCCALL 0x80010004L +#define RPC_E_CANTCALLOUT_INEXTERNALCALL 0x80010005L +#define RPC_E_CONNECTION_TERMINATED 0x80010006L +#define RPC_E_SERVER_DIED 0x80010007L +#define RPC_E_CLIENT_DIED 0x80010008L +#define RPC_E_INVALID_DATAPACKET 0x80010009L +#define RPC_E_CANTTRANSMIT_CALL 0x8001000AL +#define RPC_E_CLIENT_CANTMARSHAL_DATA 0x8001000BL +#define RPC_E_CLIENT_CANTUNMARSHAL_DATA 0x8001000CL +#define RPC_E_SERVER_CANTMARSHAL_DATA 0x8001000DL +#define RPC_E_SERVER_CANTUNMARSHAL_DATA 0x8001000EL +#define RPC_E_INVALID_DATA 0x8001000FL +#define RPC_E_INVALID_PARAMETER 0x80010010L +#define RPC_E_CANTCALLOUT_AGAIN 0x80010011L +#define RPC_E_SERVER_DIED_DNE 0x80010012L +#define RPC_E_SYS_CALL_FAILED 0x80010100L +#define RPC_E_OUT_OF_RESOURCES 0x80010101L +#define RPC_E_ATTEMPTED_MULTITHREAD 0x80010102L +#define RPC_E_NOT_REGISTERED 0x80010103L +#define RPC_E_FAULT 0x80010104L +#define RPC_E_SERVERFAULT 0x80010105L +#define RPC_E_CHANGED_MODE 0x80010106L +#define RPC_E_INVALIDMETHOD 0x80010107L +#define RPC_E_DISCONNECTED 0x80010108L +#define RPC_E_RETRY 0x80010109L +#define RPC_E_SERVERCALL_RETRYLATER 0x8001010AL +#define RPC_E_SERVERCALL_REJECTED 0x8001010BL +#define RPC_E_INVALID_CALLDATA 0x8001010CL +#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL 0x8001010DL +#define RPC_E_WRONG_THREAD 0x8001010EL +#define RPC_E_THREAD_NOT_INIT 0x8001010FL +#define RPC_E_VERSION_MISMATCH 0x80010110L +#define RPC_E_INVALID_HEADER 0x80010111L +#define RPC_E_INVALID_EXTENSION 0x80010112L +#define RPC_E_INVALID_IPID 0x80010113L +#define RPC_E_INVALID_OBJECT 0x80010114L +#define RPC_S_CALLPENDING 0x80010115L +#define RPC_S_WAITONTIMER 0x80010116L +#define RPC_E_CALL_COMPLETE 0x80010117L +#define RPC_E_UNSECURE_CALL 0x80010118L +#define RPC_E_TOO_LATE 0x80010119L +#define RPC_E_NO_GOOD_SECURITY_PACKAGES 0x8001011AL +#define RPC_E_ACCESS_DENIED 0x8001011BL +#define RPC_E_REMOTE_DISABLED 0x8001011CL +#define RPC_E_INVALID_OBJREF 0x8001011DL +#define RPC_E_NO_CONTEXT 0x8001011EL +#define RPC_E_TIMEOUT 0x8001011FL +#define RPC_E_NO_SYNC 0x80010120L +#define RPC_E_UNEXPECTED 0x8001FFFFL + +#define DISP_E_UNKNOWNINTERFACE 0x80020001L +#define DISP_E_MEMBERNOTFOUND 0x80020003L +#define DISP_E_PARAMNOTFOUND 0x80020004L +#define DISP_E_TYPEMISMATCH 0x80020005L +#define DISP_E_UNKNOWNNAME 0x80020006L +#define DISP_E_NONAMEDARGS 0x80020007L +#define DISP_E_BADVARTYPE 0x80020008L +#define DISP_E_EXCEPTION 0x80020009L +#define DISP_E_OVERFLOW 0x8002000AL +#define DISP_E_BADINDEX 0x8002000BL +#define DISP_E_UNKNOWNLCID 0x8002000CL +#define DISP_E_ARRAYISLOCKED 0x8002000DL +#define DISP_E_BADPARAMCOUNT 0x8002000EL +#define DISP_E_PARAMNOTOPTIONAL 0x8002000FL +#define DISP_E_BADCALLEE 0x80020010L +#define DISP_E_NOTACOLLECTION 0x80020011L +#define DISP_E_DIVBYZERO 0x80020012L + +#define TYPE_E_BUFFERTOOSMALL 0x80028016L +#define TYPE_E_FIELDNOTFOUND 0x80028017L +#define TYPE_E_INVDATAREAD 0x80028018L +#define TYPE_E_UNSUPFORMAT 0x80028019L +#define TYPE_E_REGISTRYACCESS 0x8002801CL +#define TYPE_E_LIBNOTREGISTERED 0x8002801DL +#define TYPE_E_UNDEFINEDTYPE 0x80028027L +#define TYPE_E_QUALIFIEDNAMEDISALLOWED 0x80028028L +#define TYPE_E_INVALIDSTATE 0x80028029L +#define TYPE_E_WRONGTYPEKIND 0x8002802AL +#define TYPE_E_ELEMENTNOTFOUND 0x8002802BL +#define TYPE_E_AMBIGUOUSNAME 0x8002802CL +#define TYPE_E_NAMECONFLICT 0x8002802DL +#define TYPE_E_UNKNOWNLCID 0x8002802EL +#define TYPE_E_DLLFUNCTIONNOTFOUND 0x8002802FL +#define TYPE_E_BADMODULEKIND 0x800288BDL +#define TYPE_E_SIZETOOBIG 0x800288C5L +#define TYPE_E_DUPLICATEID 0x800288C6L +#define TYPE_E_INVALIDID 0x800288CFL +#define TYPE_E_TYPEMISMATCH 0x80028CA0L +#define TYPE_E_OUTOFBOUNDS 0x80028CA1L +#define TYPE_E_IOERROR 0x80028CA2L +#define TYPE_E_CANTCREATETMPFILE 0x80028CA3L +#define TYPE_E_CANTLOADLIBRARY 0x80029C4AL +#define TYPE_E_INCONSISTENTPROPFUNCS 0x80029C83L +#define TYPE_E_CIRCULARTYPE 0x80029C84L + +#define STG_S_CONVERTED 0x00030200L +#define STG_S_BLOCK 0x00030201L +#define STG_S_RETRYNOW 0x00030202L +#define STG_S_MONITORING 0x00030203L +#define STG_S_MULTIPLEOPENS 0x00030204L +#define STG_S_CONSOLIDATIONFAILED 0x00030205L +#define STG_S_CANNOTCONSOLIDATE 0x00030206L + +#define STG_E_INVALIDFUNCTION 0x80030001L +#define STG_E_FILENOTFOUND 0x80030002L +#define STG_E_PATHNOTFOUND 0x80030003L +#define STG_E_TOOMANYOPENFILES 0x80030004L +#define STG_E_ACCESSDENIED 0x80030005L +#define STG_E_INVALIDHANDLE 0x80030006L +#define STG_E_INSUFFICIENTMEMORY 0x80030008L +#define STG_E_INVALIDPOINTER 0x80030009L +#define STG_E_NOMOREFILES 0x80030012L +#define STG_E_DISKISWRITEPROTECTED 0x80030013L +#define STG_E_SEEKERROR 0x80030019L +#define STG_E_WRITEFAULT 0x8003001DL +#define STG_E_READFAULT 0x8003001EL +#define STG_E_SHAREVIOLATION 0x80030020L +#define STG_E_LOCKVIOLATION 0x80030021L +#define STG_E_FILEALREADYEXISTS 0x80030050L +#define STG_E_INVALIDPARAMETER 0x80030057L +#define STG_E_MEDIUMFULL 0x80030070L +#define STG_E_ABNORMALAPIEXIT 0x800300FAL +#define STG_E_INVALIDHEADER 0x800300FBL +#define STG_E_INVALIDNAME 0x800300FCL +#define STG_E_UNKNOWN 0x800300FDL +#define STG_E_UNIMPLEMENTEDFUNCTION 0x800300FEL +#define STG_E_INVALIDFLAG 0x800300FFL +#define STG_E_INUSE 0x80030100L +#define STG_E_NOTCURRENT 0x80030101L +#define STG_E_REVERTED 0x80030102L +#define STG_E_CANTSAVE 0x80030103L +#define STG_E_OLDFORMAT 0x80030104L +#define STG_E_OLDDLL 0x80030105L +#define STG_E_SHAREREQUIRED 0x80030106L +#define STG_E_NOTFILEBASEDSTORAGE 0x80030107L +#define STG_E_EXTANTMARSHALLINGS 0x80030108L + +#define OLE_S_FIRST 0x00040000L +#define OLE_S_USEREG 0x00040000L +#define OLE_S_STATIC 0x00040001L +#define OLE_S_MAC_CLIPFORMAT 0x00040002L +#define OLE_S_LAST 0x000400FFL + +#define OLE_E_FIRST 0x80040000L +#define OLE_E_OLEVERB 0x80040000L +#define OLE_E_ADVF 0x80040001L +#define OLE_E_ENUM_NOMORE 0x80040002L +#define OLE_E_ADVISENOTSUPPORTED 0x80040003L +#define OLE_E_NOCONNECTION 0x80040004L +#define OLE_E_NOTRUNNING 0x80040005L +#define OLE_E_NOCACHE 0x80040006L +#define OLE_E_BLANK 0x80040007L +#define OLE_E_CLASSDIFF 0x80040008L +#define OLE_E_CANT_GETMONIKER 0x80040009L +#define OLE_E_CANT_BINDTOSOURCE 0x8004000AL +#define OLE_E_STATIC 0x8004000BL +#define OLE_E_PROMPTSAVECANCELLED 0x8004000CL +#define OLE_E_INVALIDRECT 0x8004000DL +#define OLE_E_WRONGCOMPOBJ 0x8004000EL +#define OLE_E_INVALIDHWND 0x8004000FL +#define OLE_E_NOT_INPLACEACTIVE 0x80040010L +#define OLE_E_CANTCONVERT 0x80040011L +#define OLE_E_NOSTORAGE 0x80040012L +#define DV_E_FORMATETC 0x80040064L +#define DV_E_DVTARGETDEVICE 0x80040065L +#define DV_E_STGMEDIUM 0x80040066L +#define DV_E_STATDATA 0x80040067L +#define DV_E_LINDEX 0x80040068L +#define DV_E_TYMED 0x80040069L +#define DV_E_CLIPFORMAT 0x8004006AL +#define DV_E_DVASPECT 0x8004006BL +#define DV_E_DVTARGETDEVICE_SIZE 0x8004006CL +#define DV_E_NOIVIEWOBJECT 0x8004006DL +#define OLE_E_LAST 0x800400FFL + +#define DRAGDROP_S_FIRST 0x00040100L +#define DRAGDROP_S_DROP 0x00040100L +#define DRAGDROP_S_CANCEL 0x00040101L +#define DRAGDROP_S_USEDEFAULTCURSORS 0x00040102L +#define DRAGDROP_S_LAST 0x0004010FL + +#define DRAGDROP_E_FIRST 0x80040100L +#define DRAGDROP_E_NOTREGISTERED 0x80040100L +#define DRAGDROP_E_ALREADYREGISTERED 0x80040101L +#define DRAGDROP_E_INVALIDHWND 0x80040102L +#define DRAGDROP_E_LAST 0x8004010FL + + +#define CLASSFACTORY_S_FIRST 0x00040110L +#define CLASSFACTORY_S_LAST 0x0004011FL + +#define CLASSFACTORY_E_FIRST 0x80040110L +#define CLASS_E_NOAGGREGATION 0x80040110L +#define CLASS_E_CLASSNOTAVAILABLE 0x80040111L +#define CLASS_E_NOTLICENSED 0x80040112L +#define CLASSFACTORY_E_LAST 0x8004011FL + +#define MARSHAL_S_FIRST 0x00040120L +#define MARSHAL_S_LAST 0x0004012FL + +#define MARSHAL_E_FIRST 0x80040120L +#define MARSHAL_E_LAST 0x8004012FL + +#define DATA_S_FIRST 0x00040130L +#define DATA_S_SAMEFORMATETC 0x00040130L +#define DATA_S_LAST 0x0004013FL + +#define DATA_E_FIRST 0x80040130L +#define DATA_E_LAST 0x8004013FL + +#define VIEW_S_FIRST 0x00040140L +#define VIEW_S_ALREADY_FROZEN 0x00040140L +#define VIEW_S_LAST 0x0004014FL + +#define VIEW_E_FIRST 0x80040140L +#define VIEW_E_DRAW 0x80040140L +#define VIEW_E_LAST 0x8004014FL + +#define REGDB_S_FIRST 0x00040150L +#define REGDB_S_LAST 0x0004015FL + +#define REGDB_E_FIRST 0x80040150L +#define REGDB_E_READREGDB 0x80040150L +#define REGDB_E_WRITEREGDB 0x80040151L +#define REGDB_E_KEYMISSING 0x80040152L +#define REGDB_E_INVALIDVALUE 0x80040153L +#define REGDB_E_CLASSNOTREG 0x80040154L +#define REGDB_E_IIDNOTREG 0x80040155L +#define REGDB_E_LAST 0x8004015FL + +#define CACHE_S_FIRST 0x00040170L +#define CACHE_S_FORMATETC_NOTSUPPORTED 0x00040170L +#define CACHE_S_SAMECACHE 0x00040171L +#define CACHE_S_SOMECACHES_NOTUPDATED 0x00040172L +#define CACHE_S_LAST 0x0004017FL + +#define CACHE_E_FIRST 0x80040170L +#define CACHE_E_NOCACHE_UPDATED 0x80040170L +#define CACHE_E_LAST 0x8004017FL + +#define OLEOBJ_S_FIRST 0x00040180L +#define OLEOBJ_S_INVALIDVERB 0x00040180L +#define OLEOBJ_S_CANNOT_DOVERB_NOW 0x00040181L +#define OLEOBJ_S_INVALIDHWND 0x00040182L +#define OLEOBJ_S_LAST 0x0004018FL + +#define OLEOBJ_E_FIRST 0x80040180L +#define OLEOBJ_E_NOVERBS 0x80040180L +#define OLEOBJ_E_INVALIDVERB 0x80040181L +#define OLEOBJ_E_LAST 0x8004018FL + +#define CLIENTSITE_S_FIRST 0x00040190L +#define CLIENTSITE_S_LAST 0x0004019FL + +#define CLIENTSITE_E_FIRST 0x80040190L +#define CLIENTSITE_E_LAST 0x8004019FL + +#define INPLACE_S_FIRST 0x000401A0L +#define INPLACE_S_TRUNCATED 0x000401A0L +#define INPLACE_S_LAST 0x000401AFL + +#define INPLACE_E_FIRST 0x800401A0L +#define INPLACE_E_NOTUNDOABLE 0x800401A0L +#define INPLACE_E_NOTOOLSPACE 0x800401A1L +#define INPLACE_E_LAST 0x800401AFL + +#define ENUM_S_FIRST 0x000401B0L +#define ENUM_S_LAST 0x000401BFL + +#define ENUM_E_FIRST 0x800401B0L +#define ENUM_E_LAST 0x800401BFL + +#define CONVERT10_S_FIRST 0x000401C0L +#define CONVERT10_S_NO_PRESENTATION 0x000401C0L +#define CONVERT10_S_LAST 0x000401CFL + +#define CONVERT10_E_FIRST 0x800401C0L +#define CONVERT10_E_OLESTREAM_GET 0x800401C0L +#define CONVERT10_E_OLESTREAM_PUT 0x800401C1L +#define CONVERT10_E_OLESTREAM_FMT 0x800401C2L +#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB 0x800401C3L +#define CONVERT10_E_STG_FMT 0x800401C4L +#define CONVERT10_E_STG_NO_STD_STREAM 0x800401C5L +#define CONVERT10_E_STG_DIB_TO_BITMAP 0x800401C6L +#define CONVERT10_E_LAST 0x800401CFL + +#define CLIPBRD_S_FIRST 0x000401D0L +#define CLIPBRD_S_LAST 0x000401DFL + +#define CLIPBRD_E_FIRST 0x800401D0L +#define CLIPBRD_E_LAST 0x800401DFL +#define CLIPBRD_E_CANT_OPEN 0x800401D0L +#define CLIPBRD_E_CANT_EMPTY 0x800401D1L +#define CLIPBRD_E_CANT_SET 0x800401D2L +#define CLIPBRD_E_BAD_DATA 0x800401D3L +#define CLIPBRD_E_CANT_CLOSE 0x800401D4L + +#define MK_S_FIRST 0x000401E0L +#define MK_S_REDUCED_TO_SELF 0x000401E2L +#define MK_S_ME 0x000401E4L +#define MK_S_HIM 0x000401E5L +#define MK_S_US 0x000401E6L +#define MK_S_MONIKERALREADYREGISTERED 0x000401E7L +#define MK_S_LAST 0x000401EFL + +#define MK_E_FIRST 0x800401E0L +#define MK_E_CONNECTMANUALLY 0x800401E0L +#define MK_E_EXCEEDEDDEADLINE 0x800401E1L +#define MK_E_NEEDGENERIC 0x800401E2L +#define MK_E_UNAVAILABLE 0x800401E3L +#define MK_E_SYNTAX 0x800401E4L +#define MK_E_NOOBJECT 0x800401E5L +#define MK_E_INVALIDEXTENSION 0x800401E6L +#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED 0x800401E7L +#define MK_E_NOTBINDABLE 0x800401E8L +#define MK_E_NOTBOUND 0x800401E9L +#define MK_E_CANTOPENFILE 0x800401EAL +#define MK_E_MUSTBOTHERUSER 0x800401EBL +#define MK_E_NOINVERSE 0x800401ECL +#define MK_E_NOSTORAGE 0x800401EDL +#define MK_E_NOPREFIX 0x800401EEL +#define MK_E_ENUMERATION_FAILED 0x800401EFL +#define MK_E_LAST 0x800401EFL + +#define CO_S_FIRST 0x000401F0L +#define CO_S_LAST 0x000401FFL + +#define CO_E_FIRST 0x800401F0L +#define CO_E_NOTINITIALIZED 0x800401F0L +#define CO_E_ALREADYINITIALIZED 0x800401F1L +#define CO_E_CANTDETERMINECLASS 0x800401F2L +#define CO_E_CLASSSTRING 0x800401F3L +#define CO_E_IIDSTRING 0x800401F4L +#define CO_E_APPNOTFOUND 0x800401F5L +#define CO_E_APPSINGLEUSE 0x800401F6L +#define CO_E_ERRORINAPP 0x800401F7L +#define CO_E_DLLNOTFOUND 0x800401F8L +#define CO_E_ERRORINDLL 0x800401F9L +#define CO_E_WRONGOSFORAPP 0x800401FAL +#define CO_E_OBJNOTREG 0x800401FBL +#define CO_E_OBJISREG 0x800401FCL +#define CO_E_OBJNOTCONNECTED 0x800401FDL +#define CO_E_APPDIDNTREG 0x800401FEL +#define CO_E_RELEASED 0x800401FFL +#define CO_E_LAST 0x800401FFL +#define CO_E_FAILEDTOIMPERSONATE 0x80040200L +#define CO_E_FAILEDTOGETSECCTX 0x80040201L +#define CO_E_FAILEDTOOPENTHREADTOKEN 0x80040202L +#define CO_E_FAILEDTOGETTOKENINFO 0x80040203L +#define CO_E_TRUSTEEDOESNTMATCHCLIENT 0x80040204L +#define CO_E_FAILEDTOQUERYCLIENTBLANKET 0x80040205L +#define CO_E_FAILEDTOSETDACL 0x80040206L +#define CO_E_ACCESSCHECKFAILED 0x80040207L +#define CO_E_NETACCESSAPIFAILED 0x80040208L +#define CO_E_WRONGTRUSTEENAMESYNTAX 0x80040209L +#define CO_E_INVALIDSID 0x8004020AL +#define CO_E_CONVERSIONFAILED 0x8004020BL +#define CO_E_NOMATCHINGSIDFOUND 0x8004020CL +#define CO_E_LOOKUPACCSIDFAILED 0x8004020DL +#define CO_E_NOMATCHINGNAMEFOUND 0x8004020EL +#define CO_E_LOOKUPACCNAMEFAILED 0x8004020FL +#define CO_E_SETSERLHNDLFAILED 0x80040210L +#define CO_E_FAILEDTOGETWINDIR 0x80040211L +#define CO_E_PATHTOOLONG 0x80040212L +#define CO_E_FAILEDTOGENUUID 0x80040213L +#define CO_E_FAILEDTOCREATEFILE 0x80040214L +#define CO_E_FAILEDTOCLOSEHANDLE 0x80040215L +#define CO_E_EXCEEDSYSACLLIMIT 0x80040216L +#define CO_E_ACESINWRONGORDER 0x80040217L +#define CO_E_INCOMPATIBLESTREAMVERSION 0x80040218L +#define CO_E_FAILEDTOOPENPROCESSTOKEN 0x80040219L +#define CO_E_DECODEFAILED 0x8004021AL +#define CO_E_ACNOTINITIALIZED 0x8004021BL + +#define E_ACCESSDENIED 0x80070005L +#define E_HANDLE 0x80070006L +#define E_OUTOFMEMORY 0x8007000EL +#define E_INVALIDARG 0x80070057L + +#define CO_S_NOTALLINTERFACES 0x00080012L + +#define CO_E_CLASS_CREATE_FAILED 0x80080001L +#define CO_E_SCM_ERROR 0x80080002L +#define CO_E_SCM_RPC_FAILURE 0x80080003L +#define CO_E_BAD_PATH 0x80080004L +#define CO_E_SERVER_EXEC_FAILURE 0x80080005L +#define CO_E_OBJSRV_RPC_FAILURE 0x80080006L +#define MK_E_NO_NORMALIZED 0x80080007L +#define CO_E_SERVER_STOPPING 0x80080008L +#define MEM_E_INVALID_ROOT 0x80080009L +#define MEM_E_INVALID_LINK 0x80080010L +#define MEM_E_INVALID_SIZE 0x80080011L + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/reactos/include/ole32/obj_base.h b/reactos/include/ole32/obj_base.h new file mode 100644 index 00000000000..da69ab5433b --- /dev/null +++ b/reactos/include/ole32/obj_base.h @@ -0,0 +1,680 @@ +/* + * This file defines the macros and types necessary to define COM interfaces, + * and the three most basic COM interfaces: IUnknown, IMalloc and IClassFactory. + */ + +#ifndef __WINE_WINE_OBJ_BASE_H +#define __WINE_WINE_OBJ_BASE_H + +/***************************************************************************** + * define ICOM_MSVTABLE_COMPAT + * to implement the microsoft com vtable compatibility workaround for g++. + * + * NOTE: Turning this option on will produce a winelib that is incompatible + * with the binary emulator. + * + * If the compiler supports the com_interface attribute, leave this off, and + * define the ICOM_USE_COM_INTERFACE_ATTRIBUTE macro below. This may also + * require the addition of the -vtable-thunks option for g++. + * + * If you aren't interested in Winelib C++ compatibility at all, leave both + * options off. + * + * The preferable method for using ICOM_USE_COM_INTERFACE_ATTRIBUTE macro + * would be to define it only for your Winelib application. This allows you + * to have both binary and Winelib compatibility for C and C++ at the same + * time :) + */ +/* #define ICOM_MSVTABLE_COMPAT 1 */ +/* #define ICOM_USE_COM_INTERFACE_ATTRIBUTE 1 */ + +/***************************************************************************** + * Defines the basic types + */ +#include "wtypes.h" +#include "guiddef.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef NONAMELESSSTRUCT +#define LISet32(li, v) ((li).HighPart = (v) < 0 ? -1 : 0, (li).LowPart = (v)) +#define ULISet32(li, v) ((li).HighPart = 0, (li).LowPart = (v)) +#else +#define LISet32(li, v) ((li).s.HighPart = (v) < 0 ? -1 : 0, (li).s.LowPart = (v)) +#define ULISet32(li, v) ((li).s.HighPart = 0, (li).s.LowPart = (v)) +#endif + +/***************************************************************************** + * GUID API + */ +HRESULT WINAPI StringFromCLSID16(REFCLSID id, LPOLESTR16*); +HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR*); + +HRESULT WINAPI CLSIDFromString16(LPCOLESTR16, CLSID *); +HRESULT WINAPI CLSIDFromString(LPCOLESTR, CLSID *); + +HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid); +HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid); + +HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID); + + +INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax); + + +/***************************************************************************** + * Macros to define a COM interface + */ +/* + * The goal of the following set of definitions is to provide a way to use the same + * header file definitions to provide both a C interface and a C++ object oriented + * interface to COM interfaces. The type of interface is selected automatically + * depending on the language but it is always possible to get the C interface in C++ + * by defining CINTERFACE. + * + * It is based on the following assumptions: + * - all COM interfaces derive from IUnknown, this should not be a problem. + * - the header file only defines the interface, the actual fields are defined + * separately in the C file implementing the interface. + * + * The natural approach to this problem would be to make sure we get a C++ class and + * virtual methods in C++ and a structure with a table of pointer to functions in C. + * Unfortunately the layout of the virtual table is compiler specific, the layout of + * g++ virtual tables is not the same as that of an egcs virtual table which is not the + * same as that generated by Visual C+. There are workarounds to make the virtual tables + * compatible via padding but unfortunately the one which is imposed to the WINE emulator + * by the Windows binaries, i.e. the Visual C++ one, is the most compact of all. + * + * So the solution I finally adopted does not use virtual tables. Instead I use inline + * non virtual methods that dereference the method pointer themselves and perform the call. + * + * Let's take Direct3D as an example: + * + * #define ICOM_INTERFACE IDirect3D + * #define IDirect3D_METHODS \ + * ICOM_METHOD1(HRESULT,Initialize, REFIID,) \ + * ICOM_METHOD2(HRESULT,EnumDevices, LPD3DENUMDEVICESCALLBACK,, LPVOID,) \ + * ICOM_METHOD2(HRESULT,CreateLight, LPDIRECT3DLIGHT*,, IUnknown*,) \ + * ICOM_METHOD2(HRESULT,CreateMaterial,LPDIRECT3DMATERIAL*,, IUnknown*,) \ + * ICOM_METHOD2(HRESULT,CreateViewport,LPDIRECT3DVIEWPORT*,, IUnknown*,) \ + * ICOM_METHOD2(HRESULT,FindDevice, LPD3DFINDDEVICESEARCH,, LPD3DFINDDEVICERESULT,) + * #define IDirect3D_IMETHODS \ + * IUnknown_IMETHODS \ + * IDirect3D_METHODS + * ICOM_DEFINE(IDirect3D,IUnknown) + * #undef ICOM_INTERFACE + * + * #ifdef ICOM_CINTERFACE + * // *** IUnknown methods *** // + * #define IDirect3D_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) + * #define IDirect3D_AddRef(p) ICOM_CALL (AddRef,p) + * #define IDirect3D_Release(p) ICOM_CALL (Release,p) + * // *** IDirect3D methods *** // + * #define IDirect3D_Initialize(p,a) ICOM_CALL1(Initialize,p,a) + * #define IDirect3D_EnumDevices(p,a,b) ICOM_CALL2(EnumDevice,p,a,b) + * #define IDirect3D_CreateLight(p,a,b) ICOM_CALL2(CreateLight,p,a,b) + * #define IDirect3D_CreateMaterial(p,a,b) ICOM_CALL2(CreateMaterial,p,a,b) + * #define IDirect3D_CreateViewport(p,a,b) ICOM_CALL2(CreateViewport,p,a,b) + * #define IDirect3D_FindDevice(p,a,b) ICOM_CALL2(FindDevice,p,a,b) + * #endif + * + * Comments: + * - The ICOM_INTERFACE macro is used in the ICOM_METHOD macros to define the type of the 'this' + * pointer. Defining this macro here saves us the trouble of having to repeat the interface + * name everywhere. Note however that because of the way macros work, a macro like ICOM_METHOD1 + * cannot use 'ICOM_INTERFACE##_VTABLE' because this would give 'ICOM_INTERFACE_VTABLE' and not + * 'IDirect3D_VTABLE'. + * - ICOM_METHODS defines the methods specific to this interface. It is then aggregated with the + * inherited methods to form ICOM_IMETHODS. + * - ICOM_IMETHODS defines the list of methods that are inheritable from this interface. It must + * be written manually (rather than using a macro to generate the equivalent code) to avoid + * macro recursion (which compilers don't like). + * - The ICOM_DEFINE finally declares all the structures necessary for the interface. We have to + * explicitly use the interface name for macro expansion reasons again. + * Inherited methods are inherited in C by using the IDirect3D_METHODS macro and the parent's + * Xxx_IMETHODS macro. In C++ we need only use the IDirect3D_METHODS since method inheritance + * is taken care of by the language. + * - In C++ the ICOM_METHOD macros generate a function prototype and a call to a function pointer + * method. This means using once 't1 p1, t2 p2, ...' and once 'p1, p2' without the types. The + * only way I found to handle this is to have one ICOM_METHOD macro per number of parameters and + * to have it take only the type information (with const if necessary) as parameters. + * The 'undef ICOM_INTERFACE' is here to remind you that using ICOM_INTERFACE in the following + * macros will not work. This time it's because the ICOM_CALL macro expansion is done only once + * the 'IDirect3D_Xxx' macro is expanded. And by that time ICOM_INTERFACE will be long gone + * anyway. + * - You may have noticed the double commas after each parameter type. This allows you to put the + * name of that parameter which I think is good for documentation. It is not required and since + * I did not know what to put there for this example (I could only find doc about IDirect3D2), + * I left them blank. + * - Finally the set of 'IDirect3D_Xxx' macros is a standard set of macros defined to ease access + * to the interface methods in C. Unfortunately I don't see any way to avoid having to duplicate + * the inherited method definitions there. This time I could have used a trick to use only one + * macro whatever the number of parameters but I prefered to have it work the same way as above. + * - You probably have noticed that we don't define the fields we need to actually implement this + * interface: reference count, pointer to other resources and miscellaneous fields. That's + * because these interfaces are just that: interfaces. They may be implemented more than once, in + * different contexts and sometimes not even in Wine. Thus it would not make sense to impose + * that the interface contains some specific fields. + * + * + * In C this gives: + * typedef struct IDirect3DVtbl IDirect3DVtbl; + * struct IDirect3D { + * IDirect3DVtbl* lpVtbl; + * }; + * struct IDirect3DVtbl { + * HRESULT (*QueryInterface)(IDirect3D* me, REFIID riid, LPVOID* ppvObj); + * ULONG (*QueryInterface)(IDirect3D* me); + * ULONG (*QueryInterface)(IDirect3D* me); + * HRESULT (*Initialize)(IDirect3D* me, REFIID a); + * HRESULT (*EnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b); + * HRESULT (*CreateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b); + * HRESULT (*CreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b); + * HRESULT (*CreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b); + * HRESULT (*FindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b); + * }; + * + * #ifdef ICOM_CINTERFACE + * // *** IUnknown methods *** // + * #define IDirect3D_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) + * #define IDirect3D_AddRef(p) (p)->lpVtbl->AddRef(p) + * #define IDirect3D_Release(p) (p)->lpVtbl->Release(p) + * // *** IDirect3D methods *** // + * #define IDirect3D_Initialize(p,a) (p)->lpVtbl->Initialize(p,a) + * #define IDirect3D_EnumDevices(p,a,b) (p)->lpVtbl->EnumDevice(p,a,b) + * #define IDirect3D_CreateLight(p,a,b) (p)->lpVtbl->CreateLight(p,a,b) + * #define IDirect3D_CreateMaterial(p,a,b) (p)->lpVtbl->CreateMaterial(p,a,b) + * #define IDirect3D_CreateViewport(p,a,b) (p)->lpVtbl->CreateViewport(p,a,b) + * #define IDirect3D_FindDevice(p,a,b) (p)->lpVtbl->FindDevice(p,a,b) + * #endif + * + * Comments: + * - IDirect3D only contains a pointer to the IDirect3D virtual/jump table. This is the only thing + * the user needs to know to use the interface. Of course the structure we will define to + * implement this interface will have more fields but the first one will match this pointer. + * - The code generated by ICOM_DEFINE defines both the structure representing the interface and + * the structure for the jump table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to + * automatically repeat the prototypes of all the inherited methods and then uses IDirect3D_METHODS + * to define the IDirect3D methods. + * - Each method is declared as a pointer to function field in the jump table. The implementation + * will fill this jump table with appropriate values, probably using a static variable, and + * initialize the lpVtbl field to point to this variable. + * - The IDirect3D_Xxx macros then just derefence the lpVtbl pointer and use the function pointer + * corresponding to the macro name. This emulates the behavior of a virtual table and should be + * just as fast. + * - This C code should be quite compatible with the Windows headers both for code that uses COM + * interfaces and for code implementing a COM interface. + * + * + * And in C++ (with gcc's g++): + * + * typedef struct IDirect3D: public IUnknown { + * private: HRESULT (*Initialize)(IDirect3D* me, REFIID a); + * public: inline HRESULT Initialize(REFIID a) { return ((IDirect3D*)t.lpVtbl)->Initialize(this,a); }; + * private: HRESULT (*EnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b); + * public: inline HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK a, LPVOID b) + * { return ((IDirect3D*)t.lpVtbl)->EnumDevices(this,a,b); }; + * private: HRESULT (*freateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b); + * public: inline HRESULT CreateLight(LPDIRECT3DLIGHT* a, IUnknown* b) + * { return ((IDirect3D*)t.lpVtbl)->CreateLight(this,a,b); }; + * private: HRESULT (*CreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b); + * public: inline HRESULT CreateMaterial(LPDIRECT3DMATERIAL* a, IUnknown* b) + * { return ((IDirect3D*)t.lpVtbl)->CreateMaterial(this,a,b); }; + * private: HRESULT (*CreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b); + * public: inline HRESULT CreateViewport(LPDIRECT3DVIEWPORT* a, IUnknown* b) + * { return ((IDirect3D*)t.lpVtbl)->CreateViewport(this,a,b); }; + * private: HRESULT (*FindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b); + * public: inline HRESULT FindDevice(LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b) + * { return ((IDirect3D*)t.lpVtbl)->FindDevice(this,a,b); }; + * }; + * + * Comments: + * - In C++ IDirect3D does double duty as both the virtual/jump table and as the interface + * definition. The reason for this is to avoid having to duplicate the mehod definitions: once + * to have the function pointers in the jump table and once to have the methods in the interface + * class. Here one macro can generate both. This means though that the first pointer, t.lpVtbl + * defined in IUnknown, must be interpreted as the jump table pointer if we interpret the + * structure as the the interface class, and as the function pointer to the QueryInterface + * method, t.QueryInterface, if we interpret the structure as the jump table. Fortunately this + * gymnastic is entirely taken care of in the header of IUnknown. + * - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions. + * - Since IDirect3D does double duty, each ICOM_METHOD macro defines both a function pointer and + * a non-vritual inline method which dereferences it and calls it. This way this method behaves + * just like a virtual method but does not create a true C++ virtual table which would break the + * structure layout. If you look at the implementation of these methods you'll notice that they + * would not work for void functions. We have to return something and fortunately this seems to + * be what all the COM methods do (otherwise we would need another set of macros). + * - Note how the ICOM_METHOD generates both function prototypes mixing types and formal parameter + * names and the method invocation using only the formal parameter name. This is the reason why + * we need different macros to handle different numbers of parameters. + * - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE + * macro is defined in which case we would not be here. + * - This C++ code works well for code that just uses COM interfaces. But it will not work with + * C++ code implement a COM interface. That's because such code assumes the interface methods + * are declared as virtual C++ methods which is not the case here. + * + * + * Implementing a COM interface. + * + * This continues the above example. This example assumes that the implementation is in C. + * + * typedef struct _IDirect3D { + * void* lpVtbl; + * // ... + * + * } _IDirect3D; + * + * static ICOM_VTABLE(IDirect3D) d3dvt; + * + * // implement the IDirect3D methods here + * + * int IDirect3D_QueryInterface(IDirect3D* me) + * { + * ICOM_THIS(IDirect3D,me); + * // ... + * } + * + * // ... + * + * static ICOM_VTABLE(IDirect3D) d3dvt = { + * ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + * IDirect3D_QueryInterface, + * IDirect3D_Add, + * IDirect3D_Add2, + * IDirect3D_Initialize, + * IDirect3D_SetWidth + * }; + * + * Comments: + * - We first define what the interface really contains. This is th e_IDirect3D structure. The + * first field must of course be the virtual table pointer. Everything else is free. + * - Then we predeclare our static virtual table variable, we will need its address in some + * methods to initialize the virtual table pointer of the returned interface objects. + * - Then we implement the interface methods. To match what has been declared in the header file + * they must take a pointer to a IDirect3D structure and we must cast it to an _IDirect3D so that + * we can manipulate the fields. This is performed by the ICOM_THIS macro. + * - Finally we initialize the virtual table. + */ + + + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define ICOM_CINTERFACE 1 +#endif + +#ifndef ICOM_CINTERFACE +/* C++ interface */ + +#define ICOM_METHOD(ret,xfn) \ + public: virtual ret CALLBACK (xfn)(void) = 0; +#define ICOM_METHOD1(ret,xfn,ta,na) \ + public: virtual ret CALLBACK (xfn)(ta a) = 0; +#define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b) = 0; +#define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c) = 0; +#define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d) = 0; +#define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e) = 0; +#define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0; +#define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0; +#define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0; +#define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i) = 0; +#define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j) = 0; +#define ICOM_METHOD11(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \ + public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k) = 0; + + +#define ICOM_VMETHOD(xfn) \ + public: virtual void CALLBACK (xfn)(void) = 0; +#define ICOM_VMETHOD1(xfn,ta,na) \ + public: virtual void CALLBACK (xfn)(ta a) = 0; +#define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \ + public: virtual void CALLBACK (xfn)(ta a,tb b) = 0; +#define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \ + public: virtual void CALLBACK (xfn)(ta a,tb b,tc c) = 0; +#define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \ + public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d) = 0; +#define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \ + public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e) = 0; +#define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \ + public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0; +#define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \ + public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0; +#define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \ + public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0; +#define ICOM_VMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \ + public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i) = 0; +#define ICOM_VMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \ + public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i, tj j) = 0; +#define ICOM_VMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \ + public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i, tj j, tk k) = 0; + + +#ifdef ICOM_USE_COM_INTERFACE_ATTRIBUTE + +#define ICOM_DEFINE(iface,ibase) \ + typedef struct iface: public ibase { \ + iface##_METHODS \ + } __attribute__ ((com_interface)); + +#else + +#define ICOM_DEFINE(iface,ibase) \ + typedef struct iface: public ibase { \ + iface##_METHODS \ + }; + +#endif /* ICOM_USE_COM_INTERFACE_ATTRIBUTE */ + +#define ICOM_VTBL(iface) (iface) + +#else +/* C interface */ + +#define ICOM_METHOD(ret,xfn) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me); +#define ICOM_METHOD1(ret,xfn,ta,na) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a); +#define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b); +#define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c); +#define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d); +#define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e); +#define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f); +#define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g); +#define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h); +#define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i); +#define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j); +#define ICOM_METHOD11(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \ + ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k); + +#define ICOM_VMETHOD(xfn) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me); +#define ICOM_VMETHOD1(xfn,ta,na) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a); +#define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b); +#define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c); +#define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d); +#define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e); +#define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f); +#define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g); +#define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,nh) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h); +#define ICOM_VMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ni) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i); +#define ICOM_VMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,nj) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j); +#define ICOM_VMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,nk) \ + void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k); + + +#define ICOM_VTABLE(iface) iface##Vtbl +#define ICOM_VFIELD(iface) ICOM_VTABLE(iface)* lpVtbl +#define ICOM_VTBL(iface) (iface)->lpVtbl + +#ifdef ICOM_MSVTABLE_COMPAT +#define ICOM_DEFINE(iface,ibase) \ + typedef struct ICOM_VTABLE(iface) ICOM_VTABLE(iface); \ + struct iface { \ + const ICOM_VFIELD(iface); \ + }; \ + struct ICOM_VTABLE(iface) { \ + long dummyRTTI1; \ + long dummyRTTI2; \ + ibase##_IMETHODS \ + iface##_METHODS \ + }; +#define ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 0,0, + +#else +#define ICOM_DEFINE(iface,ibase) \ + typedef struct ICOM_VTABLE(iface) ICOM_VTABLE(iface); \ + struct iface { \ + const ICOM_VFIELD(iface); \ + }; \ + struct ICOM_VTABLE(iface) { \ + ibase##_IMETHODS \ + iface##_METHODS \ + }; +#define ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE +#endif /* ICOM_MSVTABLE_COMPAT */ + + +#define ICOM_THIS(impl,iface) impl* const This=(impl*)iface +#define ICOM_CTHIS(impl,iface) const impl* const This=(const impl*)iface + +#endif /*ICOM_CINTERFACE */ + +#define ICOM_CALL(xfn, p) ICOM_VTBL(p)->xfn(p) +#define ICOM_CALL1(xfn, p,a) ICOM_VTBL(p)->xfn(p,a) +#define ICOM_CALL2(xfn, p,a,b) ICOM_VTBL(p)->xfn(p,a,b) +#define ICOM_CALL3(xfn, p,a,b,c) ICOM_VTBL(p)->xfn(p,a,b,c) +#define ICOM_CALL4(xfn, p,a,b,c,d) ICOM_VTBL(p)->xfn(p,a,b,c,d) +#define ICOM_CALL5(xfn, p,a,b,c,d,e) ICOM_VTBL(p)->xfn(p,a,b,c,d,e) +#define ICOM_CALL6(xfn, p,a,b,c,d,e,f) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f) +#define ICOM_CALL7(xfn, p,a,b,c,d,e,f,g) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g) +#define ICOM_CALL8(xfn, p,a,b,c,d,e,f,g,h) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h) +#define ICOM_CALL9(xfn, p,a,b,c,d,e,f,g,h,i) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h,i) +#define ICOM_CALL10(xfn, p,a,b,c,d,e,f,g,h,i,j) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h,i,j) +#define ICOM_CALL11(xfn, p,a,b,c,d,e,f,g,h,i,j,k) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h,i,j,k) + + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IClassFactory, 0x00000001L, 0, 0); +typedef struct IClassFactory IClassFactory, *LPCLASSFACTORY; + +DEFINE_OLEGUID(IID_IMalloc, 0x00000002L, 0, 0); +typedef struct IMalloc IMalloc,*LPMALLOC; + +DEFINE_OLEGUID(IID_IUnknown, 0x00000000L, 0, 0); +typedef struct IUnknown IUnknown, *LPUNKNOWN; + + +/***************************************************************************** + * IUnknown interface + */ +#define ICOM_INTERFACE IUnknown +#define IUnknown_IMETHODS \ + ICOM_METHOD2(HRESULT,QueryInterface,REFIID,riid, LPVOID*,ppvObj) \ + ICOM_METHOD (ULONG,AddRef) \ + ICOM_METHOD (ULONG,Release) +#ifdef ICOM_CINTERFACE +typedef struct ICOM_VTABLE(IUnknown) ICOM_VTABLE(IUnknown); +struct IUnknown { + ICOM_VFIELD(IUnknown); +#if defined(ICOM_USE_COM_INTERFACE_ATTRIBUTE) +} __attribute__ ((com_interface)); +#else +}; +#endif /* ICOM_US_COM_INTERFACE_ATTRIBUTE */ + +struct ICOM_VTABLE(IUnknown) { +#ifdef ICOM_MSVTABLE_COMPAT + long dummyRTTI1; + long dummyRTTI2; +#endif /* ICOM_MSVTABLE_COMPAT */ + +#else /* ICOM_CINTERFACE */ +struct IUnknown { + +#endif /* ICOM_CINTERFACE */ + + ICOM_METHOD2(HRESULT,QueryInterface,REFIID,riid, LPVOID*,ppvObj) + ICOM_METHOD (ULONG,AddRef) + ICOM_METHOD (ULONG,Release) +#if defined(ICOM_USE_COM_INTERFACE_ATTRIBUTE) +} __attribute__ ((com_interface)); +#else +}; +#endif /* ICOM_US_COM_INTERFACE_ATTRIBUTE */ + +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IUnknown_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IUnknown_AddRef(p) ICOM_CALL (AddRef,p) +#define IUnknown_Release(p) ICOM_CALL (Release,p) + +/***************************************************************************** + * IClassFactory interface + */ +#define ICOM_INTERFACE IClassFactory +#define IClassFactory_METHODS \ + ICOM_METHOD3(HRESULT,CreateInstance, LPUNKNOWN,pUnkOuter, REFIID,riid, LPVOID*,ppvObject) \ + ICOM_METHOD1(HRESULT,LockServer, BOOL,fLock) +#define IClassFactory_IMETHODS \ + IUnknown_IMETHODS \ + IClassFactory_METHODS +ICOM_DEFINE(IClassFactory,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IClassFactory_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IClassFactory_AddRef(p) ICOM_CALL (AddRef,p) +#define IClassFactory_Release(p) ICOM_CALL (Release,p) +/*** IClassFactory methods ***/ +#define IClassFactory_CreateInstance(p,a,b,c) ICOM_CALL3(CreateInstance,p,a,b,c) +#define IClassFactory_LockServer(p,a) ICOM_CALL1(LockServer,p,a) + + +/***************************************************************************** + * IMalloc interface + */ +#define ICOM_INTERFACE IMalloc +#define IMalloc_METHODS \ + ICOM_METHOD1 (LPVOID,Alloc, DWORD,cb) \ + ICOM_METHOD2 (LPVOID,Realloc, LPVOID,pv, DWORD,cb) \ + ICOM_VMETHOD1( Free, LPVOID,pv) \ + ICOM_METHOD1(DWORD, GetSize, LPVOID,pv) \ + ICOM_METHOD1(INT, DidAlloc, LPVOID,pv) \ + ICOM_METHOD (VOID, HeapMinimize) +#define IMalloc_IMETHODS \ + IUnknown_IMETHODS \ + IMalloc_METHODS +ICOM_DEFINE(IMalloc,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IMalloc_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IMalloc_AddRef(p) ICOM_CALL (AddRef,p) +#define IMalloc_Release(p) ICOM_CALL (Release,p) +/*** IMalloc methods ***/ +#define IMalloc_Alloc(p,a) ICOM_CALL1(Alloc,p,a) +#define IMalloc_Realloc(p,a,b) ICOM_CALL2(Realloc,p,a,b) +#define IMalloc_Free(p,a) ICOM_CALL1(Free,p,a) +#define IMalloc_GetSize(p,a) ICOM_CALL1(GetSize,p,a) +#define IMalloc_DidAlloc(p,a) ICOM_CALL1(DidAlloc,p,a) +#define IMalloc_HeapMinimize(p) ICOM_CALL (HeapMinimize,p) + +/* values passed to CoGetMalloc */ +#define MEMCTX_TASK 1 /* private task memory */ +#define MEMCTX_SHARED 2 /* shared memory */ +#ifdef _MAC +#define MEMCTX_MACSYSTEM 3 /* system heap on mac */ +#endif +/* mainly for internal use... */ +#define MEMCTX_UNKNOWN -1 +#define MEMCTX_SAME -2 + +HRESULT WINAPI CoGetMalloc(DWORD dwMemContext,LPMALLOC* lpMalloc); + +LPVOID WINAPI CoTaskMemAlloc(ULONG size); + +void WINAPI CoTaskMemFree(LPVOID ptr); + +/* FIXME: unimplemented */ +LPVOID WINAPI CoTaskMemRealloc(LPVOID ptr, ULONG size); + + +/***************************************************************************** + * Additional API + */ + +typedef enum tagCOINIT +{ + COINIT_APARTMENTTHREADED = 0x2, /* Apartment model */ + COINIT_MULTITHREADED = 0x0, /* OLE calls objects on any thread */ + COINIT_DISABLE_OLE1DDE = 0x4, /* Don't use DDE for Ole1 support */ + COINIT_SPEED_OVER_MEMORY = 0x8 /* Trade memory for speed */ +} COINIT; + +HRESULT WINAPI CoCreateGuid(GUID* pguid); + +HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree); + +VOID WINAPI CoFreeAllLibraries(VOID); + +VOID WINAPI CoFreeLibrary(HINSTANCE hLibrary); + +VOID WINAPI CoFreeUnusedLibraries(VOID); + +HRESULT WINAPI CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv); + +HRESULT WINAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, REFIID iid, LPVOID *ppv); + +HRESULT WINAPI CoInitialize(LPVOID lpReserved); +HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit); + +VOID WINAPI CoUninitialize(VOID); + +/* FIXME: not implemented */ +BOOL WINAPI CoIsOle1Class(REFCLSID rclsid); + +HRESULT WINAPI CoLockObjectExternal(LPUNKNOWN pUnk, BOOL fLock, BOOL fLastUnlockReleases); + +/* class registration flags; passed to CoRegisterClassObject */ +typedef enum tagREGCLS +{ + REGCLS_SINGLEUSE = 0, + REGCLS_MULTIPLEUSE = 1, + REGCLS_MULTI_SEPARATE = 2, + REGCLS_SUSPENDED = 4 +} REGCLS; + +HRESULT WINAPI CoRegisterClassObject(REFCLSID rclsid,LPUNKNOWN pUnk,DWORD dwClsContext,DWORD flags,LPDWORD lpdwRegister); + +HRESULT WINAPI CoRevokeClassObject(DWORD dwRegister); + +BOOL WINAPI IsValidInterface( + LPUNKNOWN punk); + +HRESULT WINAPI GetClassFile(LPOLESTR filePathName,CLSID *pclsid); + + +/***************************************************************************** + * COM Server dll - exports + */ +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv); +HRESULT WINAPI DllCanUnloadNow(VOID); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __WINE_WINE_OBJ_BASE_H */ diff --git a/reactos/include/ole32/obj_cache.h b/reactos/include/ole32/obj_cache.h new file mode 100644 index 00000000000..cca4e1822c2 --- /dev/null +++ b/reactos/include/ole32/obj_cache.h @@ -0,0 +1,116 @@ +/* + * Defines the COM interfaces and APIs related to structured data storage. + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_CACHE_H +#define __WINE_WINE_OBJ_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Declare the structures + */ + + +/***************************************************************************** + * Predeclare the interfaces + */ + +DEFINE_OLEGUID(IID_IOleCache, 0x0000011eL, 0, 0); +typedef struct IOleCache IOleCache, *LPOLECACHE; + +DEFINE_OLEGUID(IID_IOleCache2, 0x00000128L, 0, 0); +typedef struct IOleCache2 IOleCache2, *LPOLECACHE2; + +DEFINE_OLEGUID(IID_IOleCacheControl, 0x00000129L, 0, 0); +typedef struct IOleCacheControl IOleCacheControl, *LPOLECACHECONTROL; + +/***************************************************************************** + * IOleCache interface + */ +#define ICOM_INTERFACE IOleCache +#define IOleCache_METHODS \ + ICOM_METHOD3(HRESULT,Cache, FORMATETC*,pformatetc, DWORD,advf, DWORD*, pdwConnection) \ + ICOM_METHOD1(HRESULT,Uncache, DWORD,dwConnection) \ + ICOM_METHOD1(HRESULT,EnumCache, IEnumSTATDATA**,ppenumSTATDATA) \ + ICOM_METHOD1(HRESULT,InitCache, IDataObject*,pDataObject) \ + ICOM_METHOD3(HRESULT,SetData, FORMATETC*,pformatetc, STGMEDIUM*,pmedium, BOOL,fRelease) +#define IOleCache_IMETHODS \ + IUnknown_IMETHODS \ + IOleCache_METHODS +ICOM_DEFINE(IOleCache,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleCache_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleCache_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleCache_Release(p) ICOM_CALL (Release,p) +/*** IOleCache methods ***/ +#define IOleCache_Cache(p,a,b,c) ICOM_CALL3(Cache,p,a,b,c) +#define IOleCache_Uncache(p,a) ICOM_CALL1(Uncache,p,a) +#define IOleCache_EnumCache(p,a) ICOM_CALL1(EnumCache,p,a) +#define IOleCache_InitCache(p,a) ICOM_CALL1(InitCache,p,a) +#define IOleCache_SetData(p,a,b,c) ICOM_CALL3(SetData,p,a,b,c) + + +/***************************************************************************** + * IOleCache2 interface + */ +#define ICOM_INTERFACE IOleCache2 +#define IOleCache2_METHODS \ + ICOM_METHOD3(HRESULT,UpdateCache, LPDATAOBJECT,pDataObject, DWORD,grfUpdf, LPVOID,pReserved) \ + ICOM_METHOD1(HRESULT,DiscardCache, DWORD,dwDiscardOptions) +#define IOleCache2_IMETHODS \ + IOleCache_IMETHODS \ + IOleCache2_METHODS +ICOM_DEFINE(IOleCache2,IOleCache) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleCache2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleCache2_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleCache2_Release(p) ICOM_CALL (Release,p) +/*** IOleCache methods ***/ +#define IOleCache2_Cache(p,a,b,c) ICOM_CALL3(Cache,p,a,b,c) +#define IOleCache2_Uncache(p,a) ICOM_CALL1(Uncache,p,a) +#define IOleCache2_EnumCache(p,a) ICOM_CALL1(EnumCache,p,a) +#define IOleCache2_InitCache(p,a) ICOM_CALL1(InitCache,p,a) +#define IOleCache2_SetData(p,a,b,c) ICOM_CALL3(SetData,p,a,b,c) +/*** IOleCache2 methods ***/ +#define IOleCache2_UpdateCache(p,a,b,c) ICOM_CALL3(UpdateCache,p,a,b,c) +#define IOleCache2_DiscardCache(p,a) ICOM_CALL1(DiscardCache,p,a) + + +/***************************************************************************** + * IOleCacheControl interface + */ +#define ICOM_INTERFACE IOleCacheControl +#define IOleCacheControl_METHODS \ + ICOM_METHOD1(HRESULT,OnRun, LPDATAOBJECT,pDataObject) \ + ICOM_METHOD (HRESULT,OnStop) +#define IOleCacheControl_IMETHODS \ + IUnknown_IMETHODS \ + IOleCacheControl_METHODS +ICOM_DEFINE(IOleCacheControl,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleCacheControl_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleCacheControl_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleCacheControl_Release(p) ICOM_CALL (Release,p) +/*** IOleCacheControl methods ***/ +#define IOleCacheControl_OnRun(p,a) ICOM_CALL1(UpdateCache,p,a) +#define IOleCacheControl_OnStop(p) ICOM_CALL (OnStop,p) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_CONTROL_H */ + + diff --git a/reactos/include/ole32/obj_channel.h b/reactos/include/ole32/obj_channel.h new file mode 100644 index 00000000000..843f53eeec5 --- /dev/null +++ b/reactos/include/ole32/obj_channel.h @@ -0,0 +1,181 @@ +/* + * Defines undocumented Microsoft COM interfaces and APIs seemingly related to some 'channel' notion. + */ + +#ifndef __WINE_WINE_OBJ_CHANNEL_H +#define __WINE_WINE_OBJ_CHANNEL_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID (IID_IChannelHook, 0x1008c4a0L, 0x7613, 0x11cf, 0x9a, 0xf1, 0x00, 0x20, 0xaf, 0x6e, 0x72, 0xf4); +typedef struct IChannelHook IChannelHook,*LPCHANNELHOOK; + +DEFINE_GUID (IID_IPSFactoryBuffer, 0xd5f569d0L, 0x593b, 0x101a, 0xb5, 0x69, 0x08, 0x00, 0x2b, 0x2d, 0xbf, 0x7a); +typedef struct IPSFactoryBuffer IPSFactoryBuffer,*LPPSFACTORYBUFFER; + +DEFINE_GUID (IID_IRpcChannelBuffer, 0xd5f56b60L, 0x593b, 0x101a, 0xb5, 0x69, 0x08, 0x00, 0x2b, 0x2d, 0xbf, 0x7a); +typedef struct IRpcChannelBuffer IRpcChannelBuffer,*LPRPCCHANNELBUFFER; + +DEFINE_GUID (IID_IRpcProxyBuffer, 0xd5f56a34L, 0x593b, 0x101a, 0xb5, 0x69, 0x08, 0x00, 0x2b, 0x2d, 0xbf, 0x7a); +typedef struct IRpcProxyBuffer IRpcProxyBuffer,*LPRPCPROXYBUFFER; + +DEFINE_GUID (IID_IRpcStubBuffer, 0xd5f56afcL, 0x593b, 0x101a, 0xb5, 0x69, 0x08, 0x00, 0x2b, 0x2d, 0xbf, 0x7a); +typedef struct IRpcStubBuffer IRpcStubBuffer,*LPRPCSTUBBUFFER; + + +/***************************************************************************** + * IChannelHook interface + */ +#define ICOM_INTERFACE IChannelHook +#define IChannelHook_METHODS \ + ICOM_VMETHOD3(ClientGetSize, REFGUID,uExtent, REFIID,riid, ULONG*,pDataSize) \ + ICOM_VMETHOD4(ClientFillBuffer, REFGUID,uExtent, REFIID,riid, ULONG*,pDataSize, void*,pDataBuffer) \ + ICOM_VMETHOD6(ClientNotify, REFGUID,uExtent, REFIID,riid, ULONG,cbDataSize, void*,pDataBuffer, DWORD,lDataRep, HRESULT,hrFault) \ + ICOM_VMETHOD5(ServerNotify, REFGUID,uExtent, REFIID,riid, ULONG,cbDataSize, void*,pDataBuffer, DWORD,lDataRep) \ + ICOM_VMETHOD4(ServerGetSize, REFGUID,uExtent, REFIID,riid, HRESULT,hrFault, ULONG*,pDataSize) \ + ICOM_VMETHOD5(ServerFillBuffer, REFGUID,uExtent, REFIID,riid, ULONG*,pDataSize, void*,pDataBuffer, HRESULT,hrFault) +#define IChannelHook_IMETHODS \ + IUnknown_IMETHODS \ + IChannelHook_METHODS +ICOM_DEFINE(IChannelHook,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IChannelHook_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IChannelHook_AddRef(p) ICOM_CALL (AddRef,p) +#define IChannelHook_Release(p) ICOM_CALL (Release,p) +/*** IChannelHook methods ***/ +#define IChannelHook_ClientGetSize(p,a,b,c) ICOM_CALL(ClientGetSize,p,a,b,c) +#define IChannelHook_ClientFillBuffer(p,a,b,c,d) ICOM_CALL(ClientFillBuffer,p,a,b,c,d) +#define IChannelHook_ClientNotify(p,a,b,c,d,e,f) ICOM_CALL(ClientNotify,p,a,b,c,d,e,f) +#define IChannelHook_ServerNotify(p,a,b,c,d,e) ICOM_CALL(ServerNotify,p,a,b,c,d,e) +#define IChannelHook_ServerGetSize(p,a,b,c,d) ICOM_CALL(ServerGetSize,p,a,b,c,d) +#define IChannelHook_ServerFillBuffer(p,a,b,c,d,e) ICOM_CALL(ServerFillBuffer,p,a,b,c,d,e) + + +/***************************************************************************** + * IPSFactoryBuffer interface + */ +#define ICOM_INTERFACE IPSFactoryBuffer +#define IPSFactoryBuffer_METHODS \ + ICOM_METHOD4(HRESULT,CreateProxy, IUnknown*,pUnkOuter, REFIID,riid, IRpcProxyBuffer**,ppProxy, void**,ppv) \ + ICOM_METHOD3(HRESULT,CreateStub, REFIID,riid, IUnknown*,pUnkServer, IRpcStubBuffer**,ppStub) +#define IPSFactoryBuffer_IMETHODS \ + IUnknown_IMETHODS \ + IPSFactoryBuffer_METHODS +ICOM_DEFINE(IPSFactoryBuffer,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPSFactoryBuffer_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPSFactoryBuffer_AddRef(p) ICOM_CALL (AddRef,p) +#define IPSFactoryBuffer_Release(p) ICOM_CALL (Release,p) +/*** IPSFactoryBuffer methods ***/ +#define IPSFactoryBuffer_CreateProxy(p,a,b,c,d) ICOM_CALL4(CreateProxy,p,a,b,c,d) +#define IPSFactoryBuffer_CreateStub(p,a,b,c) ICOM_CALL3(CreateStub,p,a,b,c) + + +/***************************************************************************** + * IRpcChannelBuffer interface + */ +typedef unsigned long RPCOLEDATAREP; + +typedef struct tagRPCOLEMESSAGE +{ + void* reserved1; + RPCOLEDATAREP dataRepresentation; + void* Buffer; + ULONG cbBuffer; + ULONG iMethod; + void* reserved2[5]; + ULONG rpcFlags; +} RPCOLEMESSAGE, *PRPCOLEMESSAGE; + +#define ICOM_INTERFACE IRpcChannelBuffer +#define IRpcChannelBuffer_METHODS \ + ICOM_METHOD2(HRESULT,GetBuffer, RPCOLEMESSAGE*,pMessage, REFIID,riid) \ + ICOM_METHOD2(HRESULT,SendReceive, RPCOLEMESSAGE*,pMessage, ULONG*,pStatus) \ + ICOM_METHOD1(HRESULT,FreeBuffer, RPCOLEMESSAGE*,pMessage) \ + ICOM_METHOD2(HRESULT,GetDestCtx, DWORD*,pdwDestContext, void**,ppvDestContext) \ + ICOM_METHOD (HRESULT,IsConnected) +#define IRpcChannelBuffer_IMETHODS \ + IUnknown_IMETHODS \ + IRpcChannelBuffer_METHODS +ICOM_DEFINE(IRpcChannelBuffer,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IRpcChannelBuffer_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IRpcChannelBuffer_AddRef(p) ICOM_CALL (AddRef,p) +#define IRpcChannelBuffer_Release(p) ICOM_CALL (Release,p) +/*** IRpcChannelBuffer methods ***/ +#define IRpcChannelBuffer_GetBuffer(p,a,b) ICOM_CALL2(GetBuffer,p,a,b) +#define IRpcChannelBuffer_SendReceive(p,a,b) ICOM_CALL2(SendReceive,p,a,b) +#define IRpcChannelBuffer_FreeBuffer(p,a) ICOM_CALL1(FreeBuffer,p,a) +#define IRpcChannelBuffer_GetDestCtx(p,a,b) ICOM_CALL2(GetDestCtx,p,a,b) +#define IRpcChannelBuffer_IsConnected(p) ICOM_CALL (IsConnected,p) + + +/***************************************************************************** + * IRpcProxyBuffer interface + */ +#define ICOM_INTERFACE IRpcProxyBuffer +#define IRpcProxyBuffer_METHODS \ + ICOM_METHOD1(HRESULT,Connect, IRpcChannelBuffer*,pRpcChannelBuffer) \ + ICOM_VMETHOD( Disconnect) +#define IRpcProxyBuffer_IMETHODS \ + IUnknown_IMETHODS \ + IRpcProxyBuffer_METHODS +ICOM_DEFINE(IRpcProxyBuffer,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IRpcProxyBuffer_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IRpcProxyBuffer_AddRef(p) ICOM_CALL (AddRef,p) +#define IRpcProxyBuffer_Release(p) ICOM_CALL (Release,p) +/*** IRpcProxyBuffer methods ***/ +#define IRpcProxyBuffer_Connect(p,a) ICOM_CALL2(Connect,p,a) +#define IRpcProxyBuffer_Disconnect(p) ICOM_CALL (Disconnect,p) + + +/***************************************************************************** + * IRpcStubBuffer interface + */ +#define ICOM_INTERFACE IRpcStubBuffer +#define IRpcStubBuffer_METHODS \ + ICOM_METHOD1 (HRESULT, Connect, IUnknown*,pUnkServer) \ + ICOM_VMETHOD ( Disconnect) \ + ICOM_METHOD2 (HRESULT, Invoke, RPCOLEMESSAGE*,_prpcmsg, IRpcChannelBuffer*,_pRpcChannelBuffer) \ + ICOM_METHOD1 (LPRPCCHANNELBUFFER,IsIIDSupported, REFIID,riid) \ + ICOM_METHOD (ULONG, CountRefs) \ + ICOM_METHOD1 (HRESULT, DebugServerQueryInterface, void**,ppv) \ + ICOM_VMETHOD1( DebugServerRelease, void*,pv) +#define IRpcStubBuffer_IMETHODS \ + IUnknown_IMETHODS \ + IRpcStubBuffer_METHODS +ICOM_DEFINE(IRpcStubBuffer,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IRpcStubBuffer_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IRpcStubBuffer_AddRef(p) ICOM_CALL (AddRef,p) +#define IRpcStubBuffer_Release(p) ICOM_CALL (Release,p) +/*** IRpcStubBuffer methods ***/ +#define IRpcStubBuffer_Connect(p,a) ICOM_CALL1(Connect,p,a) +#define IRpcStubBuffer_Disconnect(p) ICOM_CALL (Disconnect,p) +#define IRpcStubBuffer_Invoke(p,a,b) ICOM_CALL2(Invoke,p,a,b) +#define IRpcStubBuffer_IsIIDSupported(p,a) ICOM_CALL1(IsIIDSupported,p,a) +#define IRpcStubBuffer_CountRefs(p) ICOM_CALL (CountRefs,p) +#define IRpcStubBuffer_DebugServerQueryInterface(p,a) ICOM_CALL1(DebugServerQueryInterface,p,a) +#define IRpcStubBuffer_DebugServerRelease(p,a) ICOM_CALL1(DebugServerRelease,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_CHANNEL_H */ diff --git a/reactos/include/ole32/obj_clientserver.h b/reactos/include/ole32/obj_clientserver.h new file mode 100644 index 00000000000..8c01cbd5cb3 --- /dev/null +++ b/reactos/include/ole32/obj_clientserver.h @@ -0,0 +1,258 @@ +/* + * Defines the COM interfaces and APIs related to client/server aspects. + */ + +#ifndef __WINE_WINE_OBJ_CLIENTSERVER_H +#define __WINE_WINE_OBJ_CLIENTSERVER_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IClientSecurity, 0x0000013dL, 0, 0); +typedef struct IClientSecurity IClientSecurity,*LPCLIENTSECURITY; + +DEFINE_OLEGUID(IID_IExternalConnection, 0x00000019L, 0, 0); +typedef struct IExternalConnection IExternalConnection,*LPEXTERNALCONNECTION; + +DEFINE_OLEGUID(IID_IMessageFilter, 0x00000016L, 0, 0); +typedef struct IMessageFilter IMessageFilter,*LPMESSAGEFILTER; + +DEFINE_OLEGUID(IID_IServerSecurity, 0x0000013eL, 0, 0); +typedef struct IServerSecurity IServerSecurity,*LPSERVERSECURITY; + + +/***************************************************************************** + * IClientSecurity interface + */ +typedef struct tagSOLE_AUTHENTICATION_SERVICE +{ + DWORD dwAuthnSvc; + DWORD dwAuthzSvc; + OLECHAR* pPrincipalName; + HRESULT hr; +} SOLE_AUTHENTICATION_SERVICE, *PSOLE_AUTHENTICATION_SERVICE; + +typedef enum tagEOLE_AUTHENTICATION_CAPABILITIES +{ + EOAC_NONE = 0x0, + EOAC_MUTUAL_AUTH = 0x1, + EOAC_SECURE_REFS = 0x2, + EOAC_ACCESS_CONTROL = 0x4 +} EOLE_AUTHENTICATION_CAPABILITIES; + +#define ICOM_INTERFACE IClientSecurity +#define IClientSecurity_METHODS \ + ICOM_METHOD8(HRESULT,QueryBlanket, IUnknown*,pProxy, DWORD*,pAuthnSvc, DWORD*,pAuthzSvc, OLECHAR**,pServerPrincName, DWORD*,pAuthnLevel, DWORD*,pImpLevel, void**,pAuthInfo, DWORD*,pCapabilites) \ + ICOM_METHOD8(HRESULT,SetBlanket, IUnknown*,pProxy, DWORD,pAuthnSvc, DWORD,pAuthzSvc, OLECHAR*,pServerPrincName, DWORD,pAuthnLevel, DWORD,pImpLevel, void*,pAuthInfo, DWORD,pCapabilites) \ + ICOM_METHOD2(HRESULT,CopyProxy, IUnknown*,pProxy, IUnknown**,ppCopy) +#define IClientSecurity_IMETHODS \ + IUnknown_IMETHODS \ + IClientSecurity_METHODS +ICOM_DEFINE(IClientSecurity,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IClientSecurity_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IClientSecurity_AddRef(p) ICOM_CALL (AddRef,p) +#define IClientSecurity_Release(p) ICOM_CALL (Release,p) +/*** IClientSecurity methods ***/ +#define IClientSecurity_QueryBlanket(p,a,b,c,d,e,f,g,h) ICOM_CALL8(QueryBlanket,p,a,b,c,d,e,f,g,h) +#define IClientSecurity_SetBlanket(p,a,b,c,d,e,f,g,h) ICOM_CALL8(SetBlanket,p,a,b,c,d,e,f,g,h) +#define IClientSecurity_CopyProxy(p,a,b) ICOM_CALL2(CopyProxy,p,a,b) + + +/***************************************************************************** + * IExternalConnection interface + */ +typedef enum tagEXTCONN +{ + EXTCONN_STRONG = 0x1, + EXTCONN_WEAK = 0x2, + EXTCONN_CALLABLE = 0x4 +} EXTCONN; + +#define ICOM_INTERFACE IExternalConnection +#define IExternalConnection_METHODS \ + ICOM_METHOD2(DWORD,AddConnection, DWORD,extconn, DWORD,reserved) \ + ICOM_METHOD3(DWORD,ReleaseConnection, DWORD,extconn, DWORD,reserved, BOOL,fLastReleaseCloses) +#define IExternalConnection_IMETHODS \ + IUnknown_IMETHODS \ + IExternalConnection_METHODS +ICOM_DEFINE(IExternalConnection,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IExternalConnection_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IExternalConnection_AddRef(p) ICOM_CALL (AddRef,p) +#define IExternalConnection_Release(p) ICOM_CALL (Release,p) +/*** IExternalConnection methods ***/ +#define IExternalConnection_AddConnection(p,a,b) ICOM_CALL8(AddConnection,p,a,b) +#define IExternalConnection_ReleaseConnection(p,a,b,c) ICOM_CALL8(ReleaseConnection,p,a,b,c) + + +HRESULT WINAPI CoDisconnectObject(LPUNKNOWN lpUnk, DWORD reserved); + + +/***************************************************************************** + * IMessageFilter interface + */ +typedef enum tagCALLTYPE +{ + CALLTYPE_TOPLEVEL = 1, + CALLTYPE_NESTED = 2, + CALLTYPE_ASYNC = 3, + CALLTYPE_TOPLEVEL_CALLPENDING = 4, + CALLTYPE_ASYNC_CALLPENDING = 5 +} CALLTYPE; + +typedef enum tagSERVERCALL +{ + SERVERCALL_ISHANDLED = 0, + SERVERCALL_REJECTED = 1, + SERVERCALL_RETRYLATER = 2 +} SERVERCALL; + +typedef enum tagPENDINGTYPE +{ + PENDINGTYPE_TOPLEVEL = 1, + PENDINGTYPE_NESTED = 2 +} PENDINGTYPE; + +typedef enum tagPENDINGMSG +{ + PENDINGMSG_CANCELCALL = 0, + PENDINGMSG_WAITNOPROCESS = 1, + PENDINGMSG_WAITDEFPROCESS = 2 +} PENDINGMSG; + +typedef struct tagINTERFACEINFO +{ + IUnknown* pUnk; + IID iid; + WORD wMethod; +} INTERFACEINFO,*LPINTERFACEINFO; + +#if 0 +#define ICOM_INTERFACE IMessageFilter +#define IMessageFilter_METHODS \ + ICOM_METHOD4(DWORD,HandleInComingCall, DWORD,dwCallType, HTASK,htaskCaller, DWORD,dwTickCount, LPINTERFACEINFO,lpInterfaceInfo) \ + ICOM_METHOD3(DWORD,RetryRejectedCall, HTASK,htaskCallee, DWORD,dwTickCount, DWORD,dwRejectType) \ + ICOM_METHOD3(DWORD,MessagePending, HTASK,htaskCallee, DWORD,dwTickCount, DWORD,dwRejectType) +#define IMessageFilter_IMETHODS \ + IUnknown_IMETHODS \ + IMessageFilter_METHODS +ICOM_DEFINE(IMessageFilter,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IMessageFilter_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IMessageFilter_AddRef(p) ICOM_CALL (AddRef,p) +#define IMessageFilter_Release(p) ICOM_CALL (Release,p) +/*** IMessageFilter methods ***/ +#define IMessageFilter_HandleInComingCall(p,a,b,c,d) ICOM_CALL4(HandleInComingCall,p,a,b,c,d) +#define IMessageFilter_RetryRejectedCall(p,a,b,c) ICOM_CALL3(RetryRejectedCall,p,a,b,c) +#define IMessageFilter_MessagePending(p,a,b,c) ICOM_CALL3(MessagePending,p,a,b,c) + + +HRESULT WINAPI CoRegisterMessageFilter16(LPMESSAGEFILTER lpMessageFilter,LPMESSAGEFILTER *lplpMessageFilter); +HRESULT WINAPI CoRegisterMessageFilter(LPMESSAGEFILTER lpMessageFilter,LPMESSAGEFILTER *lplpMessageFilter); +#endif + +/***************************************************************************** + * IServerSecurity interface + */ +#define ICOM_INTERFACE IServerSecurity +#define IServerSecurity_METHODS \ + ICOM_METHOD7(HRESULT,QueryBlanket, DWORD*,pAuthnSvc, DWORD*,pAuthzSvc, OLECHAR**,pServerPrincName, DWORD*,pAuthnLevel, DWORD*,pImpLevel, void**,pPrivs, DWORD*,pCapabilities) \ + ICOM_METHOD (HRESULT,ImpersonateClient) \ + ICOM_METHOD (HRESULT,RevertToSelf) \ + ICOM_METHOD (BOOL, IsImpersonating) +#define IServerSecurity_IMETHODS \ + IUnknown_IMETHODS \ + IServerSecurity_METHODS +ICOM_DEFINE(IServerSecurity,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IServerSecurity_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IServerSecurity_AddRef(p) ICOM_CALL (AddRef,p) +#define IServerSecurity_Release(p) ICOM_CALL (Release,p) +/*** IServerSecurity methods ***/ +#define IServerSecurity_QueryBlanket(p,a,b,c,d,e,f,g) ICOM_CALL7(QueryBlanket,p,a,b,c,d,e,f,g) +#define IServerSecurity_ImpersonateClient(p) ICOM_CALL (ImpersonateClient,p) +#define IServerSecurity_RevertToSelf(p) ICOM_CALL (RevertToSelf,p) +#define IServerSecurity_IsImpersonating(p) ICOM_CALL (IsImpersonating,p) + + +/***************************************************************************** + * Additional client API + */ +#if 0 +/* FIXME: not implemented */ +HRESULT WINAPI CoCopyProxy(IUnknown* pProxy, IUnknown** ppCopy); + +/* FIXME: not implemented */ +HRESULT WINAPI CoQueryProxyBlanket(IUnknown* pProxy, DWORD* pwAuthnSvc, DWORD* pAuthzSvc, OLECHAR** pServerPrincName, DWORD* pAuthnLevel, DWORD* pImpLevel, RPC_AUTH_IDENTITY_HANDLE* pAuthInfo, DWORD* pCapabilites); + +/* FIXME: not implemented */ +HRESULT WINAPI CoSetProxyBlanket(IUnknown* pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc, OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel, RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities); +#endif + +/***************************************************************************** + * Additional server API + */ + +#if 0 +/* FIXME: not implemented */ +ULONG WINAPI CoAddRefServerProcess(void); + +/* FIXME: not implemented */ +HRESULT WINAPI CoImpersonateClient(void); + +/* FIXME: not implemented */ +HRESULT WINAPI CoQueryClientBlanket(DWORD* pAuthnSvc, DWORD* pAuthzSvc, OLECHAR16** pServerPrincName, DWORD* pAuthnLevel, DWORD* pImpLevel, RPC_AUTHZ_HANDLE* pPrivs, DWORD* pCapabilities); + +/* FIXME: not implemented */ +HRESULT WINAPI CoReleaseServerProcess(void); + +/* FIXME: not implemented */ +HRESULT WINAPI CoRevertToSelf(void); + +/* FIXME: not implemented */ +HRESULT WINAPI CoSuspendClassObjects(void); +#endif + +/***************************************************************************** + * Additional API + */ + +/* FIXME: not implemented */ +HRESULT WINAPI CoGetCallContext(REFIID riid, void** ppInterface); + +/* FIXME: not implemented */ +HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID* pClsid); + +/* FIXME: not implemented */ +HRESULT WINAPI CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, SOLE_AUTHENTICATION_SERVICE* asAuthSvc, void* pReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void* pReserved2, DWORD dwCapabilities, void* pReserved3); + +/* FIXME: not implemented */ +BOOL WINAPI CoIsHandlerConnected(LPUNKNOWN pUnk); + +/* FIXME: not implemented */ +HRESULT WINAPI CoQueryAuthenticationServices(DWORD* pcAuthSvc, SOLE_AUTHENTICATION_SERVICE** asAuthSvc); + +/* FIXME: not implemented */ +HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid); + +/* FIXME: not implemented */ +HRESULT WINAPI CoResumeClassObjects(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_CLIENTSERVER_H */ diff --git a/reactos/include/ole32/obj_commdlgbrowser.h b/reactos/include/ole32/obj_commdlgbrowser.h new file mode 100644 index 00000000000..ac3cec110b8 --- /dev/null +++ b/reactos/include/ole32/obj_commdlgbrowser.h @@ -0,0 +1,43 @@ +/************************************************************ + * ICommDlgBrowser + */ + +#ifndef __WINE_WINE_OBJ_COMMDLGBROWSER_H +#define __WINE_WINE_OBJ_COMMDLGBROWSER_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +typedef struct ICommDlgBrowser ICommDlgBrowser, *LPCOMMDLGBROWSER; + +/* for OnStateChange*/ +#define CDBOSC_SETFOCUS 0x00000000 +#define CDBOSC_KILLFOCUS 0x00000001 +#define CDBOSC_SELCHANGE 0x00000002 +#define CDBOSC_RENAME 0x00000003 + + +#define ICOM_INTERFACE ICommDlgBrowser +#define ICommDlgBrowser_METHODS \ + ICOM_METHOD1(HRESULT, OnDefaultCommand, IShellView*, IShellView) \ + ICOM_METHOD2(HRESULT, OnStateChange, IShellView*, IShellView, ULONG, uChange) \ + ICOM_METHOD2(HRESULT, IncludeObject, IShellView*, IShellView, LPCITEMIDLIST, pidl) +#define ICommDlgBrowser_IMETHODS \ + IUnknown_IMETHODS \ + ICommDlgBrowser_METHODS +ICOM_DEFINE(ICommDlgBrowser,IUnknown) +#undef ICOM_INTERFACE + +#define ICommDlgBrowser_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ICommDlgBrowser_AddRef(p) ICOM_CALL(AddRef,p) +#define ICommDlgBrowser_Release(p) ICOM_CALL(Release,p) +#define ICommDlgBrowser_OnDefaultCommand(p,a) ICOM_CALL1(OnDefaultCommand,p,a) +#define ICommDlgBrowser_OnStateChange(p,a,b) ICOM_CALL2(OnStateChange,p,a,b) +#define ICommDlgBrowser_IncludeObject(p,a,b) ICOM_CALL2(IncludeObject,p,a,b) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_COMMDLGBROWSER_H */ diff --git a/reactos/include/ole32/obj_connection.h b/reactos/include/ole32/obj_connection.h new file mode 100644 index 00000000000..0dd92eb60ae --- /dev/null +++ b/reactos/include/ole32/obj_connection.h @@ -0,0 +1,145 @@ +/* + * Defines the COM interfaces and APIs related to structured data storage. + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_CONNECTION_H +#define __WINE_WINE_OBJ_CONNECTION_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Declare the structures + */ + +typedef struct tagCONNECTDATA +{ + IUnknown *pUnk; + DWORD dwCookie; +} CONNECTDATA, *LPCONNECTDATA; + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID(IID_IConnectionPoint, 0xb196b286, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IConnectionPoint IConnectionPoint, *LPCONNECTIONPOINT; + +DEFINE_GUID(IID_IConnectionPointContainer, 0xb196b284, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IConnectionPointContainer IConnectionPointContainer, *LPCONNECTIONPOINTCONTAINER; + +DEFINE_GUID(IID_IEnumConnections, 0xb196b287, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IEnumConnections IEnumConnections, *LPENUMCONNECTIONS; + +DEFINE_GUID(IID_IEnumConnectionPoints, 0xb196b285, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IEnumConnectionPoints IEnumConnectionPoints, *LPENUMCONNECTIONPOINTS; + +/***************************************************************************** + * IConnectionPoint interface + */ +#define ICOM_INTERFACE IConnectionPoint +#define IConnectionPoint_METHODS \ + ICOM_METHOD1(HRESULT,GetConnectionInterface, IID*,pIID) \ + ICOM_METHOD1(HRESULT,GetConnectionPointContainer, IConnectionPointContainer**,ppCPC) \ + ICOM_METHOD2(HRESULT,Advise, IUnknown*,pUnkSink, DWORD*,pdwCookie) \ + ICOM_METHOD1(HRESULT,Unadvise, DWORD,dwCookie) \ + ICOM_METHOD1(HRESULT,EnumConnections, IEnumConnections**,ppEnum) +#define IConnectionPoint_IMETHODS \ + IUnknown_IMETHODS \ + IConnectionPoint_METHODS +ICOM_DEFINE(IConnectionPoint,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IConnectionPoint_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IConnectionPoint_AddRef(p) ICOM_CALL (AddRef,p) +#define IConnectionPoint_Release(p) ICOM_CALL (Release,p) +/*** IConnectionPointContainer methods ***/ +#define IConnectionPoint_GetConnectionInterface(p,a) ICOM_CALL1(GetConnectionInterface,p,a) +#define IConnectionPoint_GetConnectionPointContainer(p,a) ICOM_CALL1(GetConnectionPointContainer,p,a) +#define IConnectionPoint_Advise(p,a,b) ICOM_CALL2(Advise,p,a,b) +#define IConnectionPoint_Unadvise(p,a) ICOM_CALL1(Unadvise,p,a) +#define IConnectionPoint_EnumConnections(p,a) ICOM_CALL1(EnumConnections,p,a) + + +/***************************************************************************** + * IConnectionPointContainer interface + */ +#define ICOM_INTERFACE IConnectionPointContainer +#define IConnectionPointContainer_METHODS \ + ICOM_METHOD1(HRESULT,EnumConnectionPoints, IEnumConnectionPoints**,ppEnum) \ + ICOM_METHOD2(HRESULT,FindConnectionPoint, REFIID,riid, IConnectionPoint**,ppCP) +#define IConnectionPointContainer_IMETHODS \ + IUnknown_IMETHODS \ + IConnectionPointContainer_METHODS +ICOM_DEFINE(IConnectionPointContainer,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IConnectionPointContainer_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IConnectionPointContainer_AddRef(p) ICOM_CALL (AddRef,p) +#define IConnectionPointContainer_Release(p) ICOM_CALL (Release,p) +/*** IConnectionPointContainer methods ***/ +#define IConnectionPointContainer_EnumConnectionPoints(p,a) ICOM_CALL1(EnumConnectionPoints,p,a) +#define IConnectionPointContainer_FindConnectionPoint(p,a,b) ICOM_CALL2(FindConnectionPoint,p,a,b) + + +/***************************************************************************** + * IEnumConnections interface + */ +#define ICOM_INTERFACE IEnumConnections +#define IEnumConnections_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,cConnections, LPCONNECTDATA,rgcd, ULONG*,pcFectched) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,cConnections) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumConnections**,ppEnum) +#define IEnumConnections_IMETHODS \ + IUnknown_IMETHODS \ + IEnumConnections_METHODS +ICOM_DEFINE(IEnumConnections,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumConnections_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumConnections_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumConnections_Release(p) ICOM_CALL (Release,p) +/*** IConnectionPointContainer methods ***/ +#define IEnumConnections_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumConnections_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumConnections_Reset(p) ICOM_CALL (Reset,p) +#define IEnumConnections_Clone(p,a) ICOM_CALL1(Clone,p,a) + +/***************************************************************************** + * IEnumConnectionPoints interface + */ +#define ICOM_INTERFACE IEnumConnectionPoints +#define IEnumConnectionPoints_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,cConnections, LPCONNECTIONPOINT*,ppCP, ULONG*,pcFectched) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,cConnections) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumConnections**,ppEnum) +#define IEnumConnectionPoints_IMETHODS \ + IUnknown_IMETHODS \ + IEnumConnectionPoints_METHODS +ICOM_DEFINE(IEnumConnectionPoints,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumConnectionPoints_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumConnectionPoints_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumConnectionPoints_Release(p) ICOM_CALL (Release,p) +/*** IConnectionPointContainer methods ***/ +#define IEnumConnectionPoints_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumConnectionPoints_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumConnectionPoints_Reset(p) ICOM_CALL (Reset,p) +#define IEnumConnectionPoints_Clone(p,a) ICOM_CALL1(Clone,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_CONTROL_H */ + + diff --git a/reactos/include/ole32/obj_contextmenu.h b/reactos/include/ole32/obj_contextmenu.h new file mode 100644 index 00000000000..30e8538a32e --- /dev/null +++ b/reactos/include/ole32/obj_contextmenu.h @@ -0,0 +1,125 @@ +/************************************************************ + * IContextMenu + * + * Undocumented: + * word95 gets a IContextMenu Interface and calls HandleMenuMsg() + * whitch should only a member of IContextMenu2. + */ + +#ifndef __WINE_WINE_OBJ_CONTEXTMENU_H +#define __WINE_WINE_OBJ_CONTEXTMENU_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +typedef struct IContextMenu IContextMenu, *LPCONTEXTMENU; + +/* QueryContextMenu uFlags */ +#define CMF_NORMAL 0x00000000 +#define CMF_DEFAULTONLY 0x00000001 +#define CMF_VERBSONLY 0x00000002 +#define CMF_EXPLORE 0x00000004 +#define CMF_NOVERBS 0x00000008 +#define CMF_CANRENAME 0x00000010 +#define CMF_NODEFAULT 0x00000020 +#define CMF_INCLUDESTATIC 0x00000040 +#define CMF_RESERVED 0xffff0000 /* View specific */ + +/* GetCommandString uFlags */ +#define GCS_VERBA 0x00000000 /* canonical verb */ +#define GCS_HELPTEXTA 0x00000001 /* help text (for status bar) */ +#define GCS_VALIDATEA 0x00000002 /* validate command exists */ +#define GCS_VERBW 0x00000004 /* canonical verb (unicode) */ +#define GCS_HELPTEXTW 0x00000005 /* help text (unicode version) */ +#define GCS_VALIDATEW 0x00000006 /* validate command exists (unicode) */ +#define GCS_UNICODE 0x00000004 /* for bit testing - Unicode string */ + +#define GCS_VERB GCS_VERBA +#define GCS_HELPTEXT GCS_HELPTEXTA +#define GCS_VALIDATE GCS_VALIDATEA + +#define CMDSTR_NEWFOLDERA "NewFolder" +#define CMDSTR_VIEWLISTA "ViewList" +#define CMDSTR_VIEWDETAILSA "ViewDetails" +static const WCHAR CMDSTR_NEWFOLDERW[] = {'N','e','w','F','o','l','d','e','r',0}; +static const WCHAR CMDSTR_VIEWLISTW [] = {'V','i','e','w','L','i','s','t',0}; +static const WCHAR CMDSTR_VIEWDETAILSW[] = {'V','i','e','w','D','e','t','a','i','l','s',0}; + +#define CMDSTR_NEWFOLDER CMDSTR_NEWFOLDERA +#define CMDSTR_VIEWLIST CMDSTR_VIEWLISTA +#define CMDSTR_VIEWDETAILS CMDSTR_VIEWDETAILSA + +#define CMIC_MASK_HOTKEY SEE_MASK_HOTKEY +#define CMIC_MASK_ICON SEE_MASK_ICON +#define CMIC_MASK_FLAG_NO_UI SEE_MASK_FLAG_NO_UI +#define CMIC_MASK_UNICODE SEE_MASK_UNICODE +#define CMIC_MASK_NO_CONSOLE SEE_MASK_NO_CONSOLE +#define CMIC_MASK_HASLINKNAME SEE_MASK_HASLINKNAME +#define CMIC_MASK_FLAG_SEP_VDM SEE_MASK_FLAG_SEPVDM +#define CMIC_MASK_HASTITLE SEE_MASK_HASTITLE +#define CMIC_MASK_ASYNCOK SEE_MASK_ASYNCOK + +#define CMIC_MASK_PTINVOKE 0x20000000 + +/*NOTE: When SEE_MASK_HMONITOR is set, hIcon is treated as hMonitor */ +typedef struct tagCMINVOKECOMMANDINFO +{ DWORD cbSize; /* sizeof(CMINVOKECOMMANDINFO) */ + DWORD fMask; /* any combination of CMIC_MASK_* */ + HWND hwnd; /* might be NULL (indicating no owner window) */ + LPCSTR lpVerb; /* either a string or MAKEINTRESOURCE(idOffset) */ + LPCSTR lpParameters; /* might be NULL (indicating no parameter) */ + LPCSTR lpDirectory; /* might be NULL (indicating no specific directory) */ + INT nShow; /* one of SW_ values for ShowWindow() API */ + + DWORD dwHotKey; + HANDLE hIcon; +} CMINVOKECOMMANDINFO, *LPCMINVOKECOMMANDINFO; + +typedef struct tagCMInvokeCommandInfoEx +{ DWORD cbSize; /* must be sizeof(CMINVOKECOMMANDINFOEX) */ + DWORD fMask; /* any combination of CMIC_MASK_* */ + HWND hwnd; /* might be NULL (indicating no owner window) */ + LPCSTR lpVerb; /* either a string or MAKEINTRESOURCE(idOffset) */ + LPCSTR lpParameters; /* might be NULL (indicating no parameter) */ + LPCSTR lpDirectory; /* might be NULL (indicating no specific directory) */ + INT nShow; /* one of SW_ values for ShowWindow() API */ + + DWORD dwHotKey; + + HANDLE hIcon; + LPCSTR lpTitle; /* For CreateProcess-StartupInfo.lpTitle */ + LPCWSTR lpVerbW; /* Unicode verb (for those who can use it) */ + LPCWSTR lpParametersW; /* Unicode parameters (for those who can use it) */ + LPCWSTR lpDirectoryW; /* Unicode directory (for those who can use it) */ + LPCWSTR lpTitleW; /* Unicode title (for those who can use it) */ + POINT ptInvoke; /* Point where it's invoked */ + +} CMINVOKECOMMANDINFOEX, *LPCMINVOKECOMMANDINFOEX; + +#define ICOM_INTERFACE IContextMenu +#define IContextMenu_METHODS \ + ICOM_METHOD5(HRESULT, QueryContextMenu, HMENU, hmenu, UINT, indexMenu, UINT, idCmdFirst, UINT, idCmdLast, UINT, uFlags) \ + ICOM_METHOD1(HRESULT, InvokeCommand, LPCMINVOKECOMMANDINFO, lpici) \ + ICOM_METHOD5(HRESULT, GetCommandString, UINT, idCmd, UINT, uType, UINT*, pwReserved, LPSTR, pszName, UINT, cchMax) \ + ICOM_METHOD3(HRESULT, HandleMenuMsg, UINT, uMsg, WPARAM, wParam, LPARAM, lParam) \ + void * guard; /*possibly another nasty entry from ContextMenu3 ?*/ +#define IContextMenu_IMETHODS \ + IUnknown_IMETHODS \ + IContextMenu_METHODS +ICOM_DEFINE(IContextMenu,IUnknown) +#undef ICOM_INTERFACE + +#define IContextMenu_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IContextMenu_AddRef(p) ICOM_CALL(AddRef,p) +#define IContextMenu_Release(p) ICOM_CALL(Release,p) +#define IContextMenu_QueryContextMenu(p,a,b,c,d,e) ICOM_CALL5(QueryContextMenu,p,a,b,c,d,e) +#define IContextMenu_InvokeCommand(p,a) ICOM_CALL1(InvokeCommand,p,a) +#define IContextMenu_GetCommandString(p,a,b,c,d,e) ICOM_CALL5(GetCommandString,p,a,b,c,d,e) +#define IContextMenu_HandleMenuMsg(p,a,b,c) ICOM_CALL3(HandleMenuMsg,p,a,b,c) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_CONTEXTMENU_H */ diff --git a/reactos/include/ole32/obj_control.h b/reactos/include/ole32/obj_control.h new file mode 100644 index 00000000000..e08d307b757 --- /dev/null +++ b/reactos/include/ole32/obj_control.h @@ -0,0 +1,458 @@ +/* + * Defines the COM interfaces and APIs related to structured data storage. + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_CONTROL_H +#define __WINE_WINE_OBJ_CONTROL_H + +struct tagMSG; + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Declare the structures + */ +typedef enum tagGUIDKIND +{ + GUIDKIND_DEFAULT_SOURCE_DISP_IID = 1 +} GUIDKIND; + +typedef enum tagREADYSTATE +{ + READYSTATE_UNINITIALIZED = 0, + READYSTATE_LOADING = 1, + READYSTATE_LOADED = 2, + READYSTATE_INTERACTIVE = 3, + READYSTATE_COMPLETE = 4 +} READYSTATE; + +typedef struct tagExtentInfo +{ + ULONG cb; + DWORD dwExtentMode; + SIZEL sizelProposed; +} DVEXTENTINFO; + +typedef struct tagVARIANT_BLOB +{ + DWORD clSize; + DWORD rpcReserved; + ULONGLONG ahData[1]; +} wireVARIANT_BLOB; + +typedef struct tagUserVARIANT +{ + wireVARIANT_BLOB pVarBlob; +} UserVARIANT; + +typedef struct tagLICINFO +{ + LONG cbLicInfo; + BOOL fRuntimeKeyAvail; + BOOL fLicVerified; +} LICINFO, *LPLICINFO; + +typedef struct tagCONTROLINFO +{ + ULONG cb; + HACCEL hAccel; + USHORT cAccel; + DWORD dwFlags; +} CONTROLINFO, *LPCONTROLINFO; + +typedef enum tagCTRLINFO +{ + CTRLINFO_EATS_RETURN = 1, + CTRLINFO_EATS_ESCAPE = 2 +} CTRLINFO; + +typedef struct tagPOINTF +{ + FLOAT x; + FLOAT y; +} POINTF, *LPPOINTF; + +typedef enum tagXFORMCOORDS +{ + XFORMCOORDS_POSITION = 0x1, + XFORMCOORDS_SIZE = 0x2, + XFORMCOORDS_HIMETRICTOCONTAINER = 0x4, + XFORMCOORDS_CONTAINERTOHIMETRIC = 0x8 +} XFORMCOORDS; + +typedef enum tagACTIVATEFLAGS +{ + ACTIVATE_WINDOWLESS = 1 +} ACTIVATE_FLAGS; + +typedef enum tagOLEDCFLAGS +{ + OLEDC_NODRAW = 0x1, + OLEDC_PAINTBKGND = 0x2, + OLEDC_OFFSCREEN = 0x4 +} OLEDCFLAGS; + +typedef enum tagDVASPECT2 +{ + DVASPECT_OPAQUE = 16, + DVASPECT_TRANSPARENT = 32 +} DVASPECT2; + +typedef enum tagHITRESULT +{ + HITRESULT_OUTSIDE = 0, + HITRESULT_TRANSPARENT = 1, + HITRESULT_CLOSE = 2, + HITRESULT_HIT = 3 +} HITRESULT; + +typedef enum tagAspectInfoFlag +{ + DVASPECTINFOFLAG_CANOPTIMIZE = 1 +} DVASPECTINFOFLAG; + +typedef struct tagAspectInfo +{ + ULONG cb; + DWORD dwFlags; +} DVASPECTINFO; + +typedef enum tagVIEWSTATUS +{ + VIEWSTATUS_OPAQUE = 1, + VIEWSTATUS_SOLIDBKGND = 2, + VIEWSTATUS_DVASPECTOPAQUE = 4, + VIEWSTATUS_DVASPECTTRANSPARENT = 8 +} VIEWSTATUS; + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID(IID_IOleControl, 0xb196b288, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IOleControl IOleControl, *LPOLECONTROL; + +DEFINE_GUID(IID_IOleControlSite, 0xb196b289, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IOleControlSite IOleControlSite, *LPOLECONTROLSITE; + +DEFINE_GUID(IID_IOleInPlaceSiteEx, 0x9c2cad80L, 0x3424, 0x11cf, 0xb6, 0x70, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8); +typedef struct IOleInPlaceSiteEx IOleInPlaceSiteEx, *LPOLEINPLACESITEEX; + +DEFINE_OLEGUID(IID_IOleInPlaceSiteWindowless, 0x00000000L, 0, 0); /* FIXME - NEED GUID */ +typedef struct IOleInPlaceSiteWindowless IOleInPlaceSiteWindowless, *LPOLEINPLACESITEWINDOWLESS; + +DEFINE_OLEGUID(IID_IOleInPlaceObjectWindowless, 0x00000000L, 0, 0); /* FIXME - NEED GUID */ +typedef struct IOleInPlaceObjectWindowless IOleInPlaceObjectWindowless, *LPOLEINPLACEOBJECTWINDOWLESS; + +DEFINE_GUID(IID_IClassFactory2, 0xb196b28f, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IClassFactory2 IClassFactory2, *LPCLASSFACTORY2; + +DEFINE_GUID(IID_IViewObjectEx, 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); /* FIXME need GUID */ +typedef struct IViewObjectEx IViewObjectEx, *LPVIEWOBJECTEX; + +DEFINE_GUID(IID_IProvideClassInfo, 0xb196b283, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IProvideClassInfo IProvideClassInfo, *LPPROVIDECLASSINFO; + +DEFINE_GUID(IID_IProvideClassInfo2, 0xa6bc3ac0, 0xdbaa, 0x11ce, 0x9d, 0xe3, 0x00, 0xaa, 0x00, 0x4b, 0xb8, 0x51); +typedef struct IProvideClassInfo2 IProvideClassInfo2, *LPPROVIDECLASSINFO2; + +/***************************************************************************** + * IOleControl interface + */ +#define ICOM_INTERFACE IOleControl +#define IOleControl_METHODS \ + ICOM_METHOD1(HRESULT,GetControlInfo, CONTROLINFO*,pCI) \ + ICOM_METHOD1(HRESULT,OnMnemonic, struct tagMSG*,pMsg) \ + ICOM_METHOD1(HRESULT,OnAmbientPropertyChange, DISPID,dispID) \ + ICOM_METHOD1(HRESULT,FreezeEvents, BOOL,bFreeze) +#define IOleControl_IMETHODS \ + IUnknown_IMETHODS \ + IOleControl_METHODS +ICOM_DEFINE(IOleControl,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleControl_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleControl_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleControl_Release(p) ICOM_CALL (Release,p) +/*** IOleControl methods ***/ +#define IOleControl_GetControlInfo(p,a) ICOM_CALL1(GetControlInfo,p,a) +#define IOleControl_OnMnemonic(p,a) ICOM_CALL1(OnMnemonic,p,a) +#define IOleControl_OnAmbientPropertyChange(p,a) ICOM_CALL1(OnAmbientPropertyChange,p,a) +#define IOleControl_FreezeEvents(p,a) ICOM_CALL1(FreezeEvents,p,a) + + +/***************************************************************************** + * IOleControlSite interface + */ +#define ICOM_INTERFACE IOleControlSite +#define IOleControlSite_METHODS \ + ICOM_METHOD (HRESULT,OnControlInfoChanged) \ + ICOM_METHOD1(HRESULT,LockInPlaceActive, BOOL,fLock) \ + ICOM_METHOD1(HRESULT,GetExtendedControl, IDispatch**,ppDisp) \ + ICOM_METHOD3(HRESULT,TransformCoords, POINTL*,pPtlHimetric, POINTF*,pPtfContainer, DWORD,dwFlags) \ + ICOM_METHOD2(HRESULT,TranslateAccelerator, struct tagMSG*,pMsg, DWORD,grfModifiers) \ + ICOM_METHOD1(HRESULT,OnFocus, BOOL,fGotFocus) \ + ICOM_METHOD (HRESULT,ShowPropertyFrame) +#define IOleControlSite_IMETHODS \ + IUnknown_IMETHODS \ + IOleControlSite_METHODS +ICOM_DEFINE(IOleControlSite,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleControlSite_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleControlSite_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleControlSite_Release(p) ICOM_CALL (Release,p) +/*** IOleControlSite methods ***/ +#define IOleControlSite_OnControlInfoChanged(p) ICOM_CALL1(OnControlInfoChanged,p) +#define IOleControlSite_LockInPlaceActive(p,a) ICOM_CALL1(LockInPlaceActive,p,a) +#define IOleControlSite_GetExtendedControl(p,a) ICOM_CALL1(GetExtendedControl,p,a) +#define IOleControlSite_TransformCoords(p,a,b,c) ICOM_CALL1(TransformCoords,p,a,b,c) +#define IOleControlSite_TranslateAccelerator(p,a,b) ICOM_CALL1(TranslateAccelerator,p,a,b) +#define IOleControlSite_OnFocus(p,a) ICOM_CALL1(OnFocus,p,a) +#define IOleControlSite_ShowPropertyFrame(p) ICOM_CALL1(ShowPropertyFrame,p) + + +/***************************************************************************** + * IOleInPlaceSiteEx interface + */ +#define ICOM_INTERFACE IOleInPlaceSiteEx +#define IOleInPlaceSiteEx_METHODS \ + ICOM_METHOD2(HRESULT,OnInPlaceActivateEx, BOOL*,pfNoRedraw, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,OnInPlaceDeactivateEx, BOOL,fNoRedraw) \ + ICOM_METHOD (HRESULT,RequestUIActivate) +#define IOleInPlaceSiteEx_IMETHODS \ + IOleInPlaceSite_IMETHODS \ + IOleInPlaceSiteEx_METHODS +ICOM_DEFINE(IOleInPlaceSiteEx,IOleInPlaceSite) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleInPlaceSiteEx_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleInPlaceSiteEx_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleInPlaceSiteEx_Release(p) ICOM_CALL (Release,p) +/*** IOleWindow methods ***/ +#define IOleInPlaceSiteEx_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IOleInPlaceSiteEx_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +/*** IOleInPlaceSite methods ***/ +#define IOleInPlaceSiteEx_CanInPlaceActivate(p) ICOM_CALL (CanInPlaceActivate,p) +#define IOleInPlaceSiteEx_OnInPlaceActivate(p) ICOM_CALL (OnInPlaceActivate,p) +#define IOleInPlaceSiteEx_OnUIActivate(p) ICOM_CALL (OnUIActivate,p) +#define IOleInPlaceSiteEx_GetWindowContext(p,a,b,c,d,e) ICOM_CALL5(GetWindowContext,p,a,b,c,d,e) +#define IOleInPlaceSiteEx_Scroll(p,a) ICOM_CALL1(Scroll,p,a) +#define IOleInPlaceSiteEx_OnUIDeactivate(p,a) ICOM_CALL1(OnUIDeactivate,p,a) +#define IOleInPlaceSiteEx_OnInPlaceDeactivate(p) ICOM_CALL (OnInPlaceDeactivate,p) +#define IOleInPlaceSiteEx_DiscardUndoState(p) ICOM_CALL (DiscardUndoState,p) +#define IOleInPlaceSiteEx_DeactivateAndUndo(p) ICOM_CALL (DeactivateAndUndo,p) +#define IOleInPlaceSiteEx_OnPosRectChange(p,a) ICOM_CALL1(OnPosRectChange,p,a) +/*** IOleInPlaceSiteEx methods ***/ +#define IOleInPlaceSiteEx_OnInPlaceActivateEx(p,a,b) ICOM_CALL2(OnInPlaceActivateEx,p,a,b) +#define IOleInPlaceSiteEx_OnInPlaceDeactivateEx(p,a) ICOM_CALL1(OnInPlaceDeactivateEx,p,a) +#define IOleInPlaceSiteEx_RequestUIActivate(p) ICOM_CALL (RequestUIActivate,p) + + +/***************************************************************************** + * IOleInPlaceSiteWindowless interface + */ +#define ICOM_INTERFACE IOleInPlaceSiteWindowless +#define IOleInPlaceSiteWindowless_METHODS \ + ICOM_METHOD (HRESULT,CanWindowlessActivate) \ + ICOM_METHOD (HRESULT,GetCapture) \ + ICOM_METHOD1(HRESULT,SetCapture, BOOL,fCapture) \ + ICOM_METHOD (HRESULT,GetFocus) \ + ICOM_METHOD1(HRESULT,SetFocus, BOOL,fFocus) \ + ICOM_METHOD3(HRESULT,GetDC, LPCRECT,pRect, DWORD,grfFlags, HDC*,phDC) \ + ICOM_METHOD1(HRESULT,ReleaseDC, HDC,hDC) \ + ICOM_METHOD2(HRESULT,InvalidateRect, LPCRECT,pRect, BOOL,fErase) \ + ICOM_METHOD2(HRESULT,InvalidateRgn, HRGN,hRgn, BOOL,fErase) \ + ICOM_METHOD4(HRESULT,ScrollRect, INT,dx, INT,dy, LPCRECT,pRectScroll, LPCRECT,pRectClip) \ + ICOM_METHOD1(HRESULT,AdjustRect, LPRECT,prc) \ + ICOM_METHOD4(HRESULT,OnDefWindowMessage, UINT,msg, WPARAM,wParam, LPARAM,lParam, LRESULT*,plResult) +#define IOleInPlaceSiteWindowless_IMETHODS \ + IOleInPlaceSite_IMETHODS \ + IOleInPlaceSiteWindowless_METHODS +ICOM_DEFINE(IOleInPlaceSiteWindowless,IOleInPlaceSite) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleInPlaceSiteWindowless_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleInPlaceSiteWindowless_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleInPlaceSiteWindowless_Release(p) ICOM_CALL (Release,p) +/*** IOleWindow methods ***/ +#define IOleInPlaceSiteWindowless_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IOleInPlaceSiteWindowless_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +/*** IOleInPlaceSitemethods ***/ +#define IOleInPlaceSiteWindowless_CanInPlaceActivate(p) ICOM_CALL (CanInPlaceActivate,p) +#define IOleInPlaceSiteWindowless_OnInPlaceActivate(p) ICOM_CALL (OnInPlaceActivate,p) +#define IOleInPlaceSiteWindowless_OnUIActivate(p) ICOM_CALL (OnUIActivate,p) +#define IOleInPlaceSiteWindowless_GetWindowContext(p,a,b,c,d,e) ICOM_CALL5(GetWindowContext,p,a,b,c,d,e) +#define IOleInPlaceSiteWindowless_Scroll(p,a) ICOM_CALL1(Scroll,p,a) +#define IOleInPlaceSiteWindowless_OnUIDeactivate(p,a) ICOM_CALL1(OnUIDeactivate,p,a) +#define IOleInPlaceSiteWindowless_OnInPlaceDeactivate(p) ICOM_CALL (OnInPlaceDeactivate,p) +#define IOleInPlaceSiteWindowless_DiscardUndoState(p) ICOM_CALL (DiscardUndoState,p) +#define IOleInPlaceSiteWindowless_DeactivateAndUndo(p) ICOM_CALL (DeactivateAndUndo,p) +#define IOleInPlaceSiteWindowless_OnPosRectChange(p,a) ICOM_CALL1(OnPosRectChange,p,a) +/*** IOleInPlaceSitemethods ***/ +#define IOleInPlaceSiteWindowless_CanWindowlessActivate(p) ICOM_CALL (CanInPlaceActivate,p) +#define IOleInPlaceSiteWindowless_GetCapture(p) ICOM_CALL (OnInPlaceActivate,p) +#define IOleInPlaceSiteWindowless_SetCapture(p,a) ICOM_CALL1(OnUIActivate,p,a) +#define IOleInPlaceSiteWindowless_GetFocus(p) ICOM_CALL (GetWindowContext,p) +#define IOleInPlaceSiteWindowless_SetFocus(p,a) ICOM_CALL1(Scroll,p,a) +#define IOleInPlaceSiteWindowless_GetDC(p,a,b,c) ICOM_CALL3(OnUIDeactivate,p,a,b,c) +#define IOleInPlaceSiteWindowless_ReleaseDC(p,a) ICOM_CALL1(OnInPlaceDeactivate,p,a) +#define IOleInPlaceSiteWindowless_InvalidateRect(p,a,b) ICOM_CALL2(DiscardUndoState,p,a,b) +#define IOleInPlaceSiteWindowless_InvalidateRgn(p,a,b) ICOM_CALL2(DeactivateAndUndo,p,a,b) +#define IOleInPlaceSiteWindowless_ScrollRect(p,a,b,c,d) ICOM_CALL4(OnPosRectChange,p,a,b,c,d) +#define IOleInPlaceSiteWindowless_AdjustRect(p,a) ICOM_CALL1(OnPosRectChange,p,a) +#define IOleInPlaceSiteWindowless_OnDefWindowMessage(p,a,b,c,d) ICOM_CALL4(OnPosRectChange,p,a,b,c,d) + + +/***************************************************************************** + * IOleInPlaceObjectWindowless interface + */ +#define ICOM_INTERFACE IOleInPlaceObjectWindowless +#define IOleInPlaceObjectWindowless_METHODS \ + ICOM_METHOD4(HRESULT,OnWindowMessage, UINT,msg, WPARAM,wParam, LPARAM,lParam, LRESULT*,plResult) \ + ICOM_METHOD1(HRESULT,GetDropTarget, IDropTarget**,ppDropTarget) +#define IOleInPlaceObjectWindowless_IMETHODS \ + IOleInPlaceObject_IMETHODS \ + IOleInPlaceObjectWindowless_METHODS +ICOM_DEFINE(IOleInPlaceObjectWindowless,IOleInPlaceObject) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleInPlaceObjectWindowless_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleInPlaceObjectWindowless_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleInPlaceObjectWindowless_Release(p) ICOM_CALL (Release,p) +/*** IOleWindow methods ***/ +#define IOleInPlaceObjectWindowless_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IOleInPlaceObjectWindowless_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +/*** IOleInPlaceObject methods ***/ +#define IOleInPlaceObjectWindowless_InPlaceDeactivate(p) ICOM_CALL (InPlaceDeactivate,p) +#define IOleInPlaceObjectWindowless_UIDeactivate(p) ICOM_CALL (UIDeactivate,p) +#define IOleInPlaceObjectWindowless_SetObjectRects(p,a,b) ICOM_CALL2(SetObjectRects,p,a,b) +#define IOleInPlaceObjectWindowless_ReactivateAndUndo(p) ICOM_CALL (ReactivateAndUndo,p) +/*** IOleInPlaceObjectWindowless methods ***/ +#define IOleInPlaceObjectWindowless_OnWindowMessage(p,a,b,c,d) ICOM_CALL4(OnWindowMessage,p,a,b,c,d) +#define IOleInPlaceObjectWindowless_GetDropTarget(p,a) ICOM_CALL1(GetDropTarget,p,a) + + +/***************************************************************************** + * IClassFactory2 interface + */ +#define ICOM_INTERFACE IClassFactory2 +#define IClassFactory2_METHODS \ + ICOM_METHOD1(HRESULT,GetLicInfo, LICINFO*,pLicInfo) \ + ICOM_METHOD2(HRESULT,RequestLicKey, DWORD,dwReserved, BSTR*,pBstrKey) \ + ICOM_METHOD5(HRESULT,CreateInstanceLic, IUnknown*,pUnkOuter, IUnknown*,pUnkReserved, REFIID,riid, BSTR,bstrKey, PVOID*,ppvObj) +#define IClassFactory2_IMETHODS \ + IClassFactory_IMETHODS \ + IClassFactory2_METHODS +ICOM_DEFINE(IClassFactory2,IClassFactory) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IClassFactory2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IClassFactory2_AddRef(p) ICOM_CALL (AddRef,p) +#define IClassFactory2_Release(p) ICOM_CALL (Release,p) +/*** IClassFactory methods ***/ +#define IClassFactory2_CreateInstance(p,a,b,c) ICOM_CALL3(CreateInstance,p,a,b,c) +#define IClassFactory2_LockServer(p,a) ICOM_CALL1(LockServer,p,a) +/*** IClassFactory2 methods ***/ +#define IClassFactory2_GetLicInfo(p,a) ICOM_CALL1(GetLicInfo,p,a) +#define IClassFactory2_RequestLicKey(p,a,b) ICOM_CALL2(RequestLicKey,p,a,b) +#define IClassFactory2_CreateInstanceLic(p,a,b,c,d,e) ICOM_CALL5(CreateInstanceLic,p,a,b,c,d,e) + + +/***************************************************************************** + * IViewObject interface + */ +#define ICOM_INTERFACE IViewObjectEx +#define IViewObjectEx_METHODS \ + ICOM_METHOD2(HRESULT,GetRect, DWORD,dwAspect, LPRECTL,pRect) \ + ICOM_METHOD1(HRESULT,GetViewStatus, DWORD*,pdwStatus) \ + ICOM_METHOD5(HRESULT,QueryHitPoint, DWORD,dwAspect, LPCRECT,pRectBounds, POINT,ptlLoc, LONG,lCloseHint, DWORD*,pHitResult) \ + ICOM_METHOD5(HRESULT,QueryHitRect, DWORD,dwAspect, LPCRECT,pRectBounds, LPCRECT,pRectLoc, LONG,lCloseHint, DWORD*,pHitResult) \ + ICOM_METHOD6(HRESULT,GetNaturalExtent, DWORD,dwAspect, LONG,lindex, DVTARGETDEVICE*,ptd, HDC,hicTargetDev, DVEXTENTINFO*,pExtentInfo, LPSIZEL,pSizel) +#define IViewObjectEx_IMETHODS \ + IViewObject2_IMETHODS \ + IViewObjectEx_METHODS +ICOM_DEFINE(IViewObjectEx,IViewObject2) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IViewObjectEx_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IViewObjectEx_AddRef(p) ICOM_CALL (AddRef,p) +#define IViewObjectEx_Release(p) ICOM_CALL (Release,p) +/*** IViewObject methods ***/ +#define IViewObjectEx_Draw(p,a,b,c,d,e,f,g,h,i,j) ICOM_CALL10(Draw,p,a,b,c,d,e,f,g,h,i,j) +#define IViewObjectEx_GetColorSet(p,a,b,c,d,e,f) ICOM_CALL6(GetColorSet,p,a,b,c,d,e,f) +#define IViewObjectEx_Freeze(p,a,b,c,d) ICOM_CALL4(Freeze,p,a,b,c,d) +#define IViewObjectEx_Unfreeze(p,a) ICOM_CALL1(Unfreeze,p,a) +#define IViewObjectEx_SetAdvise(p,a,b,c) ICOM_CALL3(SetAdvise,p,a,b,c) +#define IViewObjectEx_GetAdvise(p,a,b,c) ICOM_CALL3(GetAdvise,p,a,b,c) +/*** IViewObject2 methods ***/ +#define IViewObjectEx_GetExtent(p,a,b,c,d) ICOM_CALL4(GetExtent,p,a,b,c,d) +/*** IViewObjectEx methods ***/ +#define IViewObjectEx_GetRect(p,a,b) ICOM_CALL2(GetRect,p,a,b) +#define IViewObjectEx_GetViewStatus(p,a) ICOM_CALL1(GetViewStatus,p,a) +#define IViewObjectEx_QueryHitPoint(p,a,b,c,d,e) ICOM_CALL5(QueryHitPoint,p,a,b,c,d,e) +#define IViewObjectEx_QueryHitRect(p,a,b,c,d,e) ICOM_CALL5(QueryHitRect,p,a,b,c,d,e) +#define IViewObjectEx_GetNaturalExtent(p,a,b,c,d,e,f) ICOM_CALL6(GetNaturalExtent,p,a,b,c,d,e,f) + + +/***************************************************************************** + * IProvideClassInfo interface + */ +#ifdef __WINE__ +#undef GetClassInfo +#endif + +#define ICOM_INTERFACE IProvideClassInfo +#define IProvideClassInfo_METHODS \ + ICOM_METHOD1(HRESULT,GetClassInfo, ITypeInfo**,ppTI) +#define IProvideClassInfo_IMETHODS \ + IUnknown_IMETHODS \ + IProvideClassInfo_METHODS +ICOM_DEFINE(IProvideClassInfo,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IProvideClassInfo_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IProvideClassInfo_AddRef(p) ICOM_CALL (AddRef,p) +#define IProvideClassInfo_Release(p) ICOM_CALL (Release,p) +/*** IProvideClassInfo methods ***/ +#define IProvideClassInfo_GetClassInfo(p,a) ICOM_CALL1(GetClassInfo,p,a) + + + +/***************************************************************************** + * IProvideClassInfo2 interface + */ +#define ICOM_INTERFACE IProvideClassInfo2 +#define IProvideClassInfo2_METHODS \ + ICOM_METHOD2(HRESULT,GetGUID, DWORD,dwGuidKind, GUID*,pGUID) +#define IProvideClassInfo2_IMETHODS \ + IProvideClassInfo_IMETHODS \ + IProvideClassInfo2_METHODS +ICOM_DEFINE(IProvideClassInfo2,IProvideClassInfo) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IProvideClassInfo2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IProvideClassInfo2_AddRef(p) ICOM_CALL (AddRef,p) +#define IProvideClassInfo2_Release(p) ICOM_CALL (Release,p) +/*** IProvideClassInfo methods ***/ +#define IProvideClassInfo2_GetClassInfo(p,a) ICOM_CALL1(GetClassInfo,p,a) +/*** IProvideClassInfo2 methods ***/ +#define IProvideClassInfo2_GetGUID(p,a,b) ICOM_CALL2(GetGUID,p,a,b) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_CONTROL_H */ diff --git a/reactos/include/ole32/obj_dataobject.h b/reactos/include/ole32/obj_dataobject.h new file mode 100644 index 00000000000..25fca2d28db --- /dev/null +++ b/reactos/include/ole32/obj_dataobject.h @@ -0,0 +1,323 @@ +/* + * Defines the COM interfaces and APIs related to IDataObject. + * + */ + +#ifndef __WINE_WINE_OBJ_DATAOBJECT_H +#define __WINE_WINE_OBJ_DATAOBJECT_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the structures + */ +typedef enum tagDATADIR +{ + DATADIR_GET = 1, + DATADIR_SET = 2 +} DATADIR; + +typedef struct DVTARGETDEVICE16 DVTARGETDEVICE16, *LPDVTARGETDEVICE16; +typedef struct DVTARGETDEVICE DVTARGETDEVICE, *LPDVTARGETDEVICE; + +typedef struct FORMATETC16 FORMATETC16, *LPFORMATETC16; +typedef struct FORMATETC FORMATETC, *LPFORMATETC; + +typedef struct STGMEDIUM STGMEDIUM, *LPSTGMEDIUM; + + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IAdviseSink, 0x0000010fL, 0, 0); +typedef struct IAdviseSink IAdviseSink,*LPADVISESINK; + +DEFINE_OLEGUID(IID_IAdviseSink2, 0x00000125L, 0, 0); +typedef struct IAdviseSink2 IAdviseSink2,*LPADVISESINK2; + +DEFINE_OLEGUID(IID_IDataAdviseHolder, 0x00000110L, 0, 0); +typedef struct IDataAdviseHolder IDataAdviseHolder,*LPDATAADVISEHOLDER; + +DEFINE_OLEGUID(IID_IDataObject, 0x0000010EL, 0, 0); +typedef struct IDataObject IDataObject,*LPDATAOBJECT; + +DEFINE_OLEGUID(IID_IEnumFORMATETC, 0x00000103L, 0, 0); +typedef struct IEnumFORMATETC IEnumFORMATETC,*LPENUMFORMATETC; + +DEFINE_OLEGUID(IID_IEnumSTATDATA, 0x00000105L, 0, 0); +typedef struct IEnumSTATDATA IEnumSTATDATA,*LPENUMSTATDATA; + + +/***************************************************************************** + * DVTARGETDEVICE structure + */ +struct DVTARGETDEVICE +{ + DWORD tdSize; + WORD tdDriverNameOffset; + WORD tdDeviceNameOffset; + WORD tdPortNameOffset; + WORD tdExtDevmodeOffset; + BYTE tdData[1]; +}; + + +/***************************************************************************** + * FORMATETC structure + */ +/* wished data format */ +struct FORMATETC +{ + CLIPFORMAT cfFormat; + DVTARGETDEVICE* ptd; + DWORD dwAspect; + LONG lindex; + DWORD tymed; +}; + + +/***************************************************************************** + * STGMEDIUM structure + */ +typedef enum tagTYMED +{ + TYMED_HGLOBAL = 1, + TYMED_FILE = 2, + TYMED_ISTREAM = 4, + TYMED_ISTORAGE = 8, + TYMED_GDI = 16, + TYMED_MFPICT = 32, + TYMED_ENHMF = 64, + TYMED_NULL = 0 +} TYMED; + +typedef struct tagRemSTGMEDIUM +{ + DWORD tymed; + DWORD dwHandleType; + unsigned long pData; + unsigned long pUnkForRelease; + unsigned long cbData; + BYTE data[1]; +} RemSTGMEDIUM; + +/* dataobject as answer to a request */ +struct STGMEDIUM +{ + DWORD tymed; + union { + HBITMAP hBitmap; + HMETAFILEPICT hMetaFilePict; + HENHMETAFILE hEnhMetaFile; + HGLOBAL hGlobal; + LPOLESTR lpszFileName; + IStream *pstm; + IStorage *pstg; + } u; + IUnknown *pUnkForRelease; +}; + +typedef enum tagADVF +{ + ADVF_NODATA = 1, + ADVF_PRIMEFIRST = 2, + ADVF_ONLYONCE = 4, + ADVF_DATAONSTOP = 64, + ADVFCACHE_NOHANDLER = 8, + ADVFCACHE_FORCEBUILTIN = 16, + ADVFCACHE_ONSAVE = 32 +} ADVF; + +typedef struct tagSTATDATA +{ + FORMATETC formatetc; + DWORD advf; + IAdviseSink *pAdvSink; + DWORD dwConnection; +} STATDATA, *LPSTATDATA; + +/***************************************************************************** + * IAdviseSink interface + */ +#define ICOM_INTERFACE IAdviseSink +#define IAdviseSink_METHODS \ + ICOM_VMETHOD2(OnDataChange, FORMATETC*,pFormatetc, STGMEDIUM*,pStgmed) \ + ICOM_VMETHOD2(OnViewChange, DWORD,dwAspect, LONG,lindex) \ + ICOM_VMETHOD1(OnRename, IMoniker*,pmk) \ + ICOM_VMETHOD (OnSave) \ + ICOM_VMETHOD (OnClose) +#define IAdviseSink_IMETHODS \ + IUnknown_IMETHODS \ + IAdviseSink_METHODS +ICOM_DEFINE(IAdviseSink,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IAdviseSink_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IAdviseSink_AddRef(p) ICOM_CALL (AddRef,p) +#define IAdviseSink_Release(p) ICOM_CALL (Release,p) +/*** IAdviseSink methods ***/ +#define IAdviseSink_OnDataChange(p,a,b) ICOM_CALL2(OnDataChange,p,a,b) +#define IAdviseSink_OnViewChange(p,a,b) ICOM_CALL2(OnViewChange,p,a,b) +#define IAdviseSink_OnRename(p,a) ICOM_CALL1(OnRename,p,a) +#define IAdviseSink_OnSave(p) ICOM_CALL (OnSave,p) +#define IAdviseSink_OnClose(p) ICOM_CALL (OnClose,p) + + +/***************************************************************************** + * IAdviseSink2 interface + */ +#define ICOM_INTERFACE IAdviseSink2 +#define IAdviseSink2_METHODS \ + ICOM_VMETHOD1(OnLinkSrcChange, IMoniker*,pmk) +#define IAdviseSink2_IMETHODS \ + IAdviseSink_IMETHODS \ + IAdviseSink2_METHODS +ICOM_DEFINE(IAdviseSink2,IAdviseSink) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IAdviseSink2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IAdviseSink2_AddRef(p) ICOM_CALL (AddRef,p) +#define IAdviseSink2_Release(p) ICOM_CALL (Release,p) +/*** IAdviseSink methods ***/ +#define IAdviseSink2_OnDataChange(p,a,b) ICOM_CALL2(IAdviseSink,OnDataChange,p,a,b) +#define IAdviseSink2_OnViewChange(p,a,b) ICOM_CALL2(IAdviseSink,OnViewChange,p,a,b) +#define IAdviseSink2_OnRename(p,a) ICOM_CALL1(IAdviseSink,OnRename,p,a) +#define IAdviseSink2_OnSave(p) ICOM_CALL (IAdviseSink,OnSave,p) +#define IAdviseSink2_OnClose(p) ICOM_CALL (IAdviseSink,OnClose,p) +/*** IAdviseSink2 methods ***/ +#define IAdviseSink2_OnLinkSrcChange(p,a) ICOM_CALL(OnLinkSrcChange,p,a) + + +/***************************************************************************** + * IDataAdviseHolder interface + */ +#define ICOM_INTERFACE IDataAdviseHolder +#define IDataAdviseHolder_METHODS \ + ICOM_METHOD5(HRESULT,Advise, IDataObject*,pDataObject, FORMATETC*,pFetc, DWORD,advf, IAdviseSink*,pAdvise, DWORD*,pdwConnection) \ + ICOM_METHOD1(HRESULT,Unadvise, DWORD,dwConnection) \ + ICOM_METHOD1(HRESULT,EnumAdvise, IEnumSTATDATA**,ppenumAdvise) \ + ICOM_METHOD3(HRESULT,SendOnDataChange, IDataObject*,pDataObject, DWORD,dwReserved, DWORD,advf) +#define IDataAdviseHolder_IMETHODS \ + IUnknown_IMETHODS \ + IDataAdviseHolder_METHODS +ICOM_DEFINE(IDataAdviseHolder,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IDataAdviseHolder_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDataAdviseHolder_AddRef(p) ICOM_CALL (AddRef,p) +#define IDataAdviseHolder_Release(p) ICOM_CALL (Release,p) +/*** IDataAdviseHolder methods ***/ +#define IDataAdviseHolder_Advise(p,a,b,c,d,e) ICOM_CALL5(Advise,p,a,b,c,d,e) +#define IDataAdviseHolder_Unadvise(p,a) ICOM_CALL1(Unadvise,p,a) +#define IDataAdviseHolder_EnumAdvise(p,a) ICOM_CALL1(EnumAdvise,p,a) +#define IDataAdviseHolder_SendOnDataChange(p,a,b,c) ICOM_CALL3(SendOnDataChange,p,a,b,c) + +/* FIXME: not implemented */ +HRESULT WINAPI CreateDataAdviseHolder(LPDATAADVISEHOLDER* ppDAHolder); + + +/***************************************************************************** + * IDataObject interface + */ +#define ICOM_INTERFACE IDataObject +#define IDataObject_METHODS \ + ICOM_METHOD2(HRESULT,GetData, LPFORMATETC,pformatetcIn, STGMEDIUM*,pmedium) \ + ICOM_METHOD2(HRESULT,GetDataHere, LPFORMATETC,pformatetc, STGMEDIUM*,pmedium) \ + ICOM_METHOD1(HRESULT,QueryGetData, LPFORMATETC,pformatetc) \ + ICOM_METHOD2(HRESULT,GetCanonicalFormatEtc, LPFORMATETC,pformatectIn, LPFORMATETC,pformatetcOut) \ + ICOM_METHOD3(HRESULT,SetData, LPFORMATETC,pformatetc, STGMEDIUM*,pmedium, BOOL,fRelease) \ + ICOM_METHOD2(HRESULT,EnumFormatEtc, DWORD,dwDirection, IEnumFORMATETC**,ppenumFormatEtc) \ + ICOM_METHOD4(HRESULT,DAdvise, FORMATETC*,pformatetc, DWORD,advf, IAdviseSink*,pAdvSink, DWORD*,pdwConnection) \ + ICOM_METHOD1(HRESULT,DUnadvise, DWORD,dwConnection) \ + ICOM_METHOD1(HRESULT,EnumDAdvise, IEnumSTATDATA**,ppenumAdvise) +#define IDataObject_IMETHODS \ + IUnknown_IMETHODS \ + IDataObject_METHODS +ICOM_DEFINE(IDataObject,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IDataObject_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDataObject_AddRef(p) ICOM_CALL (AddRef,p) +#define IDataObject_Release(p) ICOM_CALL (Release,p) +/*** IDataObject methods ***/ +#define IDataObject_GetData(p,a,b) ICOM_CALL2(GetData,p,a,b) +#define IDataObject_GetDataHere(p,a,b) ICOM_CALL2(GetDataHere,p,a,b) +#define IDataObject_QueryGetData(p,a) ICOM_CALL1(QueryGetData,p,a) +#define IDataObject_GetCanonicalFormatEtc(p,a,b) ICOM_CALL2(GetCanonicalFormatEtc,p,a,b) +#define IDataObject_SetData(p,a,b,c) ICOM_CALL3(SetData,p,a,b,c) +#define IDataObject_EnumFormatEtc(p,a,b) ICOM_CALL2(EnumFormatEtc,p,a,b) +#define IDataObject_DAdvise(p,a,b,c,d) ICOM_CALL4(DAdvise,p,a,b,c,d) +#define IDataObject_DUnadvise(p,a) ICOM_CALL1(DUnadvise,p,a) +#define IDataObject_EnumDAdvise(p,a) ICOM_CALL1(EnumDAdvise,p,a) + + +/***************************************************************************** + * IEnumFORMATETC interface + */ +#define ICOM_INTERFACE IEnumFORMATETC +#define IEnumFORMATETC_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, FORMATETC*,rgelt, ULONG*,pceltFethed) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumFORMATETC**,ppenum) +#define IEnumFORMATETC_IMETHODS \ + IUnknown_IMETHODS \ + IEnumFORMATETC_METHODS +ICOM_DEFINE(IEnumFORMATETC,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumFORMATETC_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumFORMATETC_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumFORMATETC_Release(p) ICOM_CALL (Release,p) +/*** IEnumFORMATETC methods ***/ +#define IEnumFORMATETC_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumFORMATETC_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumFORMATETC_Reset(p) ICOM_CALL (Reset,p) +#define IEnumFORMATETC_Clone(p,a) ICOM_CALL1(Clone,p,a) + + +/***************************************************************************** + * IEnumSTATDATA interface + */ +#define ICOM_INTERFACE IEnumSTATDATA +#define IEnumSTATDATA_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, STATDATA*,rgelt, ULONG*,pceltFethed) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumSTATDATA**,ppenum) +#define IEnumSTATDATA_IMETHODS \ + IUnknown_IMETHODS \ + IEnumSTATDATA_METHODS +ICOM_DEFINE(IEnumSTATDATA,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumSTATDATA_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumSTATDATA_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumSTATDATA_Release(p) ICOM_CALL (Release,p) +/*** IEnumSTATDATA methods ***/ +#define IEnumSTATDATA_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumSTATDATA_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumSTATDATA_Reset(p) ICOM_CALL (Reset,p) +#define IEnumSTATDATA_Clone(p,a) ICOM_CALL1(Clone,p,a) + + +/***************************************************************************** + * Additional API + */ + +/* FIXME: not implemented */ +HRESULT WINAPI CreateDataCache(LPUNKNOWN pUnkOuter, REFCLSID rclsid, REFIID iid, LPVOID* ppv); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_DATAOBJECT_H */ diff --git a/reactos/include/ole32/obj_dockingwindowframe.h b/reactos/include/ole32/obj_dockingwindowframe.h new file mode 100644 index 00000000000..da94b8d4057 --- /dev/null +++ b/reactos/include/ole32/obj_dockingwindowframe.h @@ -0,0 +1,45 @@ +/************************************************************ + * IDockingWindowFrame + */ + +#ifndef __WINE_WINE_OBJ_DOCKINGWINDOWFRAME_H +#define __WINE_WINE_OBJ_DOCKINGWINDOWFRAME_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +typedef struct IDockingWindowFrame IDockingWindowFrame, *LPDOCKINGWINDOWFRAME; +DEFINE_GUID (IID_IDockingWindowFrame, 0x47D2657AL, 0x7B27, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); + +#define DWFRF_NORMAL 0x0000 /* femove toolbar flags*/ +#define DWFRF_DELETECONFIGDATA 0x0001 +#define DWFAF_HIDDEN 0x0001 /* add tolbar*/ + +#define ICOM_INTERFACE IDockingWindowFrame +#define IDockingWindowFrame_METHODS \ + ICOM_METHOD3(HRESULT, AddToolbar, IUnknown*, punkSrc, LPCWSTR, pwszItem, DWORD, dwAddFlags) \ + ICOM_METHOD2(HRESULT, RemoveToolbar, IUnknown*, punkSrc, DWORD, dwRemoveFlags) \ + ICOM_METHOD3(HRESULT, FindToolbar, LPCWSTR, pwszItem, REFIID, riid, LPVOID*, ppvObj) +#define IDockingWindowFrame_IMETHODS \ + IOleWindow_IMETHODS \ + IDockingWindowFrame_METHODS +ICOM_DEFINE(IDockingWindowFrame,IOleWindow) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IDockingWindowFrame_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDockingWindowFrame_AddRef(p) ICOM_CALL(AddRef,p) +#define IDockingWindowFrame_Release(p) ICOM_CALL(Release,p) +/*** IDockingWindowFrame methods ***/ +#define IDockingWindowFrame_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IDockingWindowFrame_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +#define IDockingWindowFrame_AddToolbar(p,a,b,c) ICOM_CALL3(AddToolbar,p,a,b,c) +#define IDockingWindowFrame_RemoveToolbar(p,a,b) ICOM_CALL2(RemoveToolbar,p,a,b) +#define IDockingWindowFrame_FindToolbar(p,a,b,c) ICOM_CALL3(FindToolbar,p,a,b,c) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_DOCKINGWINDOWFRAME_H */ diff --git a/reactos/include/ole32/obj_dragdrop.h b/reactos/include/ole32/obj_dragdrop.h new file mode 100644 index 00000000000..3410be51239 --- /dev/null +++ b/reactos/include/ole32/obj_dragdrop.h @@ -0,0 +1,91 @@ +/* + * Defines the COM interfaces and APIs related to OLE Drag and Drop. + */ + +#ifndef __WINE_WINE_OBJ_DRAGDROP_H +#define __WINE_WINE_OBJ_DRAGDROP_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IDropSource, 0x00000121L, 0, 0); +typedef struct IDropSource IDropSource,*LPDROPSOURCE; + +DEFINE_OLEGUID(IID_IDropTarget, 0x00000122L, 0, 0); +typedef struct IDropTarget IDropTarget,*LPDROPTARGET; + +/***************************************************************************** + * DROPEFFECT enumeration + */ +#define MK_ALT (0x20) +#define DROPEFFECT_NONE 0 +#define DROPEFFECT_COPY 1 +#define DROPEFFECT_MOVE 2 +#define DROPEFFECT_LINK 4 +#define DROPEFFECT_SCROLL 0x80000000 +#define DD_DEFSCROLLINSET 11 +#define DD_DEFSCROLLDELAY 50 +#define DD_DEFSCROLLINTERVAL 50 +#define DD_DEFDRAGDELAY 50 +#define DD_DEFDRAGMINDIST 2 + +/***************************************************************************** + * IDropSource interface + */ +#define ICOM_INTERFACE IDropSource +#define IDropSource_METHODS \ + ICOM_METHOD2(HRESULT, QueryContinueDrag, BOOL, fEscapePressed, DWORD, grfKeyState) \ + ICOM_METHOD1(HRESULT, GiveFeedback, DWORD, dwEffect) +#define IDropSource_IMETHODS \ + IUnknown_IMETHODS \ + IDropSource_METHODS +ICOM_DEFINE(IDropSource,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IDropSource_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDropSource_AddRef(p) ICOM_CALL (AddRef,p) +#define IDropSource_Release(p) ICOM_CALL (Release,p) +/*** IDropSource methods ***/ +#define IDropSource_QueryContinueDrag(p,a,b) ICOM_CALL2(QueryContinueDrag,p,a,b) +#define IDropSource_GiveFeedback(p,a) ICOM_CALL1(GiveFeedback,p,a) + +/***************************************************************************** + * IDropTarget interface + */ +#define ICOM_INTERFACE IDropTarget +#define IDropTarget_METHODS \ + ICOM_METHOD4(HRESULT, DragEnter, IDataObject*, pDataObject, DWORD, grfKeyState, POINTL, pt, DWORD*, pdwEffect) \ + ICOM_METHOD3(HRESULT, DragOver, DWORD, grfKeyState, POINTL, pt, DWORD*, pdwEffect) \ + ICOM_METHOD(HRESULT, DragLeave) \ + ICOM_METHOD4(HRESULT, Drop, IDataObject*, pDataObject, DWORD, grfKeyState, POINTL, pt, DWORD*, pdwEffect) +#define IDropTarget_IMETHODS \ + IUnknown_IMETHODS \ + IDropTarget_METHODS +ICOM_DEFINE(IDropTarget,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IDropTarget_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDropTarget_AddRef(p) ICOM_CALL (AddRef,p) +#define IDropTarget_Release(p) ICOM_CALL (Release,p) +/*** IDropTarget methods ***/ +#define IDropTarget_DragEnter(p,a,b,c,d) ICOM_CALL4(DragEnter,p,a,b,c,d) +#define IDropTarget_DragOver(p,a,b,c) ICOM_CALL3(DragOver,p,a,b,c) +#define IDropTarget_DragLeave(p) ICOM_CALL(DragLeave,p) +#define IDropTarget_Drop(p,a,b,c,d) ICOM_CALL4(Drop,p,a,b,c,d) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_DRAGDROP_H */ + + + + + diff --git a/reactos/include/ole32/obj_enumidlist.h b/reactos/include/ole32/obj_enumidlist.h new file mode 100644 index 00000000000..d27da2c3859 --- /dev/null +++ b/reactos/include/ole32/obj_enumidlist.h @@ -0,0 +1,45 @@ +/* + * Defines the COM interfaces and APIs related to EnumIDList + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_ENUMIDLIST_H +#define __WINE_WINE_OBJ_ENUMIDLIST_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +typedef struct IEnumIDList IEnumIDList, *LPENUMIDLIST; + +#define ICOM_INTERFACE IEnumIDList +#define IEnumIDList_METHODS \ + ICOM_METHOD3(HRESULT, Next, ULONG, celt, LPITEMIDLIST*, rgelt, ULONG*, pceltFetched) \ + ICOM_METHOD1(HRESULT, Skip, ULONG, celt) \ + ICOM_METHOD (HRESULT, Reset) \ + ICOM_METHOD1(HRESULT, Clone, IEnumIDList**, ppenum) +#define IEnumIDList_IMETHODS \ + IUnknown_IMETHODS \ + IEnumIDList_METHODS +ICOM_DEFINE(IEnumIDList,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumIDList_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumIDList_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumIDList_Release(p) ICOM_CALL (Release,p) +/*** IEnumIDList methods ***/ +#define IEnumIDList_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumIDList_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumIDList_Reset(p) ICOM_CALL(Reset,p) +#define IEnumIDList_Clone(p,a) ICOM_CALL1(Clone,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_ENUMIDLIST_H */ diff --git a/reactos/include/ole32/obj_errorinfo.h b/reactos/include/ole32/obj_errorinfo.h new file mode 100644 index 00000000000..2e3e816cd7f --- /dev/null +++ b/reactos/include/ole32/obj_errorinfo.h @@ -0,0 +1,94 @@ +/* + * Defines the COM interfaces and APIs related to ErrorInfo + */ + +#ifndef __WINE_WINE_OBJ_ERRORINFO_H +#define __WINE_WINE_OBJ_ERRORINFO_H + +DEFINE_GUID(IID_IErrorInfo,0x1CF2B120,0x547D,0x101B,0x8E,0x65,0x08,0x00,0x2B,0x2B,0xD1,0x19); +typedef struct IErrorInfo IErrorInfo,*LPERRORINFO; + +DEFINE_GUID(IID_ICreateErrorInfo,0x22F03340,0x547D,0x101B,0x8E,0x65,0x08,0x00,0x2B,0x2B,0xD1,0x19); +typedef struct ICreateErrorInfo ICreateErrorInfo,*LPCREATEERRORINFO; + +DEFINE_GUID(IID_ISupportErrorInfo,0xDF0B3D60,0x547D,0x101B,0x8E,0x65,0x08,0x00,0x2B,0x2B,0xD1,0x19); +typedef struct ISupportErrorInfo ISupportErrorInfo,*LPSUPPORTERRORINFO; + +/***************************************************************************** + * IErrorInfo + */ +#define ICOM_INTERFACE IErrorInfo +#define IErrorInfo_METHODS \ + ICOM_METHOD1(HRESULT, GetGUID, GUID * , pGUID) \ + ICOM_METHOD1(HRESULT, GetSource, BSTR* ,pBstrSource) \ + ICOM_METHOD1(HRESULT, GetDescription, BSTR*, pBstrDescription) \ + ICOM_METHOD1(HRESULT, GetHelpFile, BSTR*, pBstrHelpFile) \ + ICOM_METHOD1(HRESULT, GetHelpContext, DWORD*, pdwHelpContext) + +#define IErrorInfo_IMETHODS \ + IUnknown_IMETHODS \ + IErrorInfo_METHODS +ICOM_DEFINE(IErrorInfo, IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IErrorInfo_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IErrorInfo_AddRef(p) ICOM_CALL (AddRef,p) +#define IErrorInfo_Release(p) ICOM_CALL (Release,p) +/*** IErrorInfo methods ***/ +#define IErrorInfo_GetGUID(p,a) ICOM_CALL1 (GetGUID,p,a) +#define IErrorInfo_GetSource(p,a) ICOM_CALL1 (GetSource,p,a) +#define IErrorInfo_GetDescription(p,a) ICOM_CALL1 (GetDescription,p,a) +#define IErrorInfo_GetHelpFile(p,a) ICOM_CALL1 (GetHelpFile,p,a) +#define IErrorInfo_GetHelpContext(p,a) ICOM_CALL1 (GetHelpContext,p,a) + +/***************************************************************************** + * ICreateErrorInfo + */ +#define ICOM_INTERFACE ICreateErrorInfo +#define ICreateErrorInfo_METHODS \ + ICOM_METHOD1(HRESULT, SetGUID, REFGUID, rguid) \ + ICOM_METHOD1(HRESULT, SetSource, LPOLESTR, szSource) \ + ICOM_METHOD1(HRESULT, SetDescription, LPOLESTR, szDescription) \ + ICOM_METHOD1(HRESULT, SetHelpFile, LPOLESTR, szHelpFile) \ + ICOM_METHOD1(HRESULT, SetHelpContext, DWORD, dwHelpContext) + +#define ICreateErrorInfo_IMETHODS \ + IUnknown_IMETHODS \ + ICreateErrorInfo_METHODS +ICOM_DEFINE(ICreateErrorInfo, IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ICreateErrorInfo_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ICreateErrorInfo_AddRef(p) ICOM_CALL (AddRef,p) +#define ICreateErrorInfo_Release(p) ICOM_CALL (Release,p) +/*** ICreateErrorInfo methods ***/ +#define ICreateErrorInfo_SetGUID(p,a) ICOM_CALL1 (SetGUID,p,a) +#define ICreateErrorInfo_SetSource(p,a) ICOM_CALL1 (SetSource,p,a) +#define ICreateErrorInfo_SetDescription(p,a) ICOM_CALL1 (SetDescription,p,a) +#define ICreateErrorInfo_SetHelpFile(p,a) ICOM_CALL1 (SetHelpFile,p,a) +#define ICreateErrorInfo_SetHelpContext(p,a) ICOM_CALL1 (SetHelpContext,p,a) + +/***************************************************************************** + * ISupportErrorInfo + */ +#define ICOM_INTERFACE ISupportErrorInfo +#define ISupportErrorInfo_METHODS \ + ICOM_METHOD1(HRESULT, InterfaceSupportsErrorInfo, REFIID, riid ) + +#define ISupportErrorInfo_IMETHODS \ + IUnknown_IMETHODS \ + ISupportErrorInfo_METHODS +ICOM_DEFINE(ISupportErrorInfo, IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ISupportErrorInfo_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ISupportErrorInfo_AddRef(p) ICOM_CALL (AddRef,p) +#define ISupportErrorInfo_Release(p) ICOM_CALL (Release,p) +/*** ISupportErrorInfo methods ***/ +#define ISupportErrorInfo_InterfaceSupportsErrorInfo(p,a) ICOM_CALL1 (InterfaceSupportsErrorInfo,p,a) + + +#endif /* __WINE_WINE_OBJ_ERRORINFO_H */ diff --git a/reactos/include/ole32/obj_extracticon.h b/reactos/include/ole32/obj_extracticon.h new file mode 100644 index 00000000000..f8e96a95f1b --- /dev/null +++ b/reactos/include/ole32/obj_extracticon.h @@ -0,0 +1,51 @@ +/************************************************************ + * IExtractIconA + */ + +#ifndef __WINE_WINE_OBJ_EXTRACTICON_H +#define __WINE_WINE_OBJ_EXTRACTICON_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +#define IID_IExtractIcon WINELIB_NAME_AW(IID_IExtractIcon) + +typedef struct IExtractIconA IExtractIconA,*LPEXTRACTICONA; +#define LPEXTRACTICON WINELIB_NAME_AW(LPEXTRACTICON) + +/* GetIconLocation() input flags*/ +#define GIL_OPENICON 0x0001 /* allows containers to specify an "open" look */ +#define GIL_FORSHELL 0x0002 /* icon is to be displayed in a ShellFolder */ +#define GIL_ASYNC 0x0020 /* this is an async extract, return E_ASYNC */ + +/* GetIconLocation() return flags */ +#define GIL_SIMULATEDOC 0x0001 /* simulate this document icon for this */ +#define GIL_PERINSTANCE 0x0002 /* icons from this class are per instance (each file has its own) */ +#define GIL_PERCLASS 0x0004 /* icons from this class per class (shared for all files of this type) */ +#define GIL_NOTFILENAME 0x0008 /* location is not a filename, must call ::ExtractIcon */ +#define GIL_DONTCACHE 0x0010 /* this icon should not be cached */ + + +#define ICOM_INTERFACE IExtractIconA +#define IExtractIconA_METHODS \ + ICOM_METHOD5(HRESULT, GetIconLocation, UINT, uFlags, LPSTR, szIconFile, UINT, cchMax, INT*, piIndex, UINT *, pwFlags) \ + ICOM_METHOD5(HRESULT, Extract, LPCSTR, pszFile, UINT, nIconIndex, HICON*, phiconLarge, HICON*, phiconSmall, UINT, nIconSize) +#define IExtractIconA_IMETHODS \ + IUnknown_IMETHODS \ + IExtractIconA_METHODS +ICOM_DEFINE(IExtractIconA,IUnknown) +#undef ICOM_INTERFACE + +#define IExtractIconA_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IExtractIconA_AddRef(p) ICOM_CALL(AddRef,p) +#define IExtractIconA_Release(p) ICOM_CALL(Release,p) +#define IExtractIconA_GetIconLocation(p,a,b,c,d,e) ICOM_CALL5(GetIconLocation,p,a,b,c,d,e) +#define IExtractIconA_Extract(p,a,b,c,d,e) ICOM_CALL5(Extract,p,a,b,c,d,e) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_EXTRACTICON_H */ + diff --git a/reactos/include/ole32/obj_inplace.h b/reactos/include/ole32/obj_inplace.h new file mode 100644 index 00000000000..344238b0fef --- /dev/null +++ b/reactos/include/ole32/obj_inplace.h @@ -0,0 +1,482 @@ +/* + * Defines the COM interfaces and APIs related to structured data storage. + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_INPLACE_H +#define __WINE_WINE_OBJ_INPLACE_H + +struct tagMSG; + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the structures + */ +typedef struct tagOleMenuGroupWidths +{ + LONG width[ 6 ]; +} OLEMENUGROUPWIDTHS, *LPOLEMENUGROUPWIDTHS; + + +typedef struct tagOleInPlaceFrameInfo +{ + UINT cb; + BOOL fMDIApp; + HWND hwndFrame; + HACCEL haccel; + UINT cAccelEntries; +} OLEINPLACEFRAMEINFO, *LPOLEINPLACEFRAMEINFO; + +typedef enum tagOLEGETMONIKER +{ + OLEGETMONIKER_ONLYIFTHERE = 1, + OLEGETMONIKER_FORCEASSIGN = 2, + OLEGETMONIKER_UNASSIGN = 3, + OLEGETMONIKER_TEMPFORUSER = 4 +} OLEGETMONIKER; + +typedef enum tagOLERENDER +{ + OLERENDER_NONE = 0, + OLERENDER_DRAW = 1, + OLERENDER_FORMAT = 2, + OLERENDER_ASIS = 3 +} OLERENDER; + +typedef enum tagUSERCLASSTYPE +{ + USERCLASSTYPE_FULL = 1, + USERCLASSTYPE_SHORT = 2, + USERCLASSTYPE_APPNAME = 3 +} USERCLASSTYPE; + +typedef enum tagOLECLOSE +{ + OLECLOSE_SAVEIFDIRTY = 1, + OLECLOSE_NOSAVE = 2, + OLECLOSE_PROMPTSAVE = 3 +} OLECLOSE; + +typedef enum tagOLEUPDATE +{ + OLEUPDATE_ALWAYS = 1, + OLEUPDATE_ONCALL = 3 +} OLEUPDATE, *LPOLEUPDATE; + +typedef struct tagOLEVERB +{ + LONG lVerb; + LPOLESTR lpszVerbName; + DWORD fuFlags; + DWORD grfAttribs; +} OLEVERB, *LPOLEVERB; + +typedef enum tagOLELINKBIND +{ + OLELINKBIND_EVENIFCLASSDIFF = 1 +} OLELINKBIND; + +typedef enum tagOLEWHICHMK +{ + OLEWHICHMK_CONTAINER = 1, + OLEWHICHMK_OBJREL = 2, + OLEWHICHMK_OBJFULL = 3 +} OLEWHICHMK; + +typedef enum tagBINDSPEED +{ + BINDSPEED_INDEFINITE = 1, + BINDSPEED_MODERATE = 2, + BINDSPEED_IMMEDIATE = 3 +} BINDSPEED; + +typedef enum tagOLECONTF +{ + OLECONTF_EMBEDDINGS = 1, + OLECONTF_LINKS = 2, + OLECONTF_OTHERS = 4, + OLECONTF_OLNYUSER = 8, + OLECONTF_ONLYIFRUNNING = 16 +} OLECONTF; + +typedef HGLOBAL HOLEMENU; +typedef LPRECT LPBORDERWIDTHS; +typedef LPCRECT LPCBORDERWIDTHS; + + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IOleWindow, 0x00000114L, 0, 0); +typedef struct IOleWindow IOleWindow, *LPOLEWINDOW; + +DEFINE_OLEGUID(IID_IOleInPlaceObject, 0x00000113L, 0, 0); +typedef struct IOleInPlaceObject IOleInPlaceObject, *LPOLEINPLACEOBJECT; + +DEFINE_OLEGUID(IID_IOleInPlaceActiveObject, 0x00000117L, 0, 0); +typedef struct IOleInPlaceActiveObject IOleInPlaceActiveObject, *LPOLEINPLACEACTIVEOBJECT; + +DEFINE_OLEGUID(IID_IOleInPlaceUIWindow, 0x00000115L, 0, 0); +typedef struct IOleInPlaceUIWindow IOleInPlaceUIWindow, *LPOLEINPLACEUIWINDOW; + +DEFINE_OLEGUID(IID_IOleInPlaceFrame, 0x00000116L, 0, 0); +typedef struct IOleInPlaceFrame IOleInPlaceFrame, *LPOLEINPLACEFRAME; + +DEFINE_OLEGUID(IID_IOleInPlaceSite, 0x00000119L, 0, 0); +typedef struct IOleInPlaceSite IOleInPlaceSite, *LPOLEINPLACESITE; + +DEFINE_OLEGUID(IID_IOleClientSite, 0x00000118L, 0, 0); +typedef struct IOleClientSite IOleClientSite, *LPOLECLIENTSITE; + +DEFINE_OLEGUID(IID_IOleContainer, 0x0000011bL, 0, 0); +typedef struct IOleContainer IOleContainer, *LPOLECONTAINER; + +DEFINE_OLEGUID(IID_IParseDisplayName, 0x0000011aL, 0, 0); +typedef struct IParseDisplayName IParseDisplayName, *LPPARSEDISPLAYNAME; + +DEFINE_OLEGUID(IID_IOleItemContainer, 0x0000011cL, 0, 0); +typedef struct IOleItemContainer IOleItemContainer, *LPOLEITEMCONTAINER; + +DEFINE_OLEGUID(IID_IOleLink, 0x0000011dL, 0, 0); +typedef struct IOleLink IOleLink, *LPOLELINK; + +/***************************************************************************** + * IOleWindow interface + */ +#define ICOM_INTERFACE IOleWindow +#define IOleWindow_METHODS \ + ICOM_METHOD1(HRESULT,GetWindow, HWND*,phwnd) \ + ICOM_METHOD1(HRESULT,ContextSensitiveHelp, BOOL,fEnterMode) +#define IOleWindow_IMETHODS \ + IUnknown_IMETHODS \ + IOleWindow_METHODS +ICOM_DEFINE(IOleWindow,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleWindow_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleWindow_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleWindow_Release(p) ICOM_CALL (Release,p) +/*** IOleWindow methods ***/ +#define IOleWindow_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IOleWindow_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) + + +/***************************************************************************** + * IOleInPlaceObject interface + */ +#define ICOM_INTERFACE IOleInPlaceObject +#define IOleInPlaceObject_METHODS \ + ICOM_METHOD (HRESULT,InPlaceDeactivate) \ + ICOM_METHOD (HRESULT,UIDeactivate) \ + ICOM_METHOD2(HRESULT,SetObjectRects, LPCRECT,lprcPosRect, LPCRECT,lprcClipRect) \ + ICOM_METHOD (HRESULT,ReactivateAndUndo) +#define IOleInPlaceObject_IMETHODS \ + IOleWindow_IMETHODS \ + IOleInPlaceObject_METHODS +ICOM_DEFINE(IOleInPlaceObject,IOleWindow) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleInPlaceObject_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleInPlaceObject_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleInPlaceObject_Release(p) ICOM_CALL (Release,p) +/*** IOleWindow methods ***/ +#define IOleInPlaceObject_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IOleInPlaceObject_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +/*** IOleInPlaceObject methods ***/ +#define IOleInPlaceObject_InPlaceDeactivate(p) ICOM_CALL (InPlaceDeactivate,p) +#define IOleInPlaceObject_UIDeactivate(p) ICOM_CALL (UIDeactivate,p) +#define IOleInPlaceObject_SetObjectRects(p,a,b) ICOM_CALL2(SetObjectRects,p,a,b) +#define IOleInPlaceObject_ReactivateAndUndo(p) ICOM_CALL (ReactivateAndUndo,p) + +/***************************************************************************** + * IOleInPlaceActiveObject interface + */ +#define ICOM_INTERFACE IOleInPlaceActiveObject +#define IOleInPlaceActiveObject_METHODS \ + ICOM_METHOD1(HRESULT,TranslateAccelerator, struct tagMSG*,lpmsg) \ + ICOM_METHOD1(HRESULT,OnFrameWindowActivate, BOOL,fActivate) \ + ICOM_METHOD1(HRESULT,OnDocWindowActivate, BOOL,fActivate) \ + ICOM_METHOD3(HRESULT,ResizeBorder, LPCRECT,prcBorder, IOleInPlaceUIWindow*,pUIWindow, BOOL,fWindowFrame) \ + ICOM_METHOD1(HRESULT,EnableModeless, BOOL,fEnable) +#define IOleInPlaceActiveObject_IMETHODS \ + IOleWindow_IMETHODS \ + IOleInPlaceActiveObject_METHODS +ICOM_DEFINE(IOleInPlaceActiveObject,IOleWindow) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleInPlaceActiveObject_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleInPlaceActiveObject_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleInPlaceActiveObject_Release(p) ICOM_CALL (Release,p) +/*** IOleWindow methods ***/ +#define IOleInPlaceActiveObject_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IOleInPlaceActiveObject_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +/*** IOleInPlaceActiveObject methods ***/ +#define IOleInPlaceActiveObject_TranslateAccelerator(p,a) ICOM_CALL1(TranslateAccelerator,p,a) +#define IOleInPlaceActiveObject_OnFrameWindowActivate(p,a) ICOM_CALL1(OnFrameWindowActivate,p,a) +#define IOleInPlaceActiveObject_OnDocWindowActivate(p,a) ICOM_CALL1(OnDocWindowActivate,p,a) +#define IOleInPlaceActiveObject_ResizeBorder(p,a,b,c) ICOM_CALL3(ResizeBorder,p,a,b,c) +#define IOleInPlaceActiveObject_EnableModeless(p,a) ICOM_CALL1(EnableModeless,p,a) + +/***************************************************************************** + * IOleInPlaceUIWindow interface + */ +#define ICOM_INTERFACE IOleInPlaceUIWindow +#define IOleInPlaceUIWindow_METHODS \ + ICOM_METHOD1(HRESULT,GetBorder, LPRECT,lprectBorder) \ + ICOM_METHOD1(HRESULT,RequestBorderSpace, LPCBORDERWIDTHS,pborderwidths) \ + ICOM_METHOD1(HRESULT,SetBorderSpace, LPCBORDERWIDTHS,pborderwidths) \ + ICOM_METHOD2(HRESULT,SetActiveObject, IOleInPlaceActiveObject*,pActiveObject, LPCOLESTR,pszObjName) +#define IOleInPlaceUIWindow_IMETHODS \ + IOleWindow_IMETHODS \ + IOleInPlaceUIWindow_METHODS +ICOM_DEFINE(IOleInPlaceUIWindow,IOleWindow) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleInPlaceUIWindow_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleInPlaceUIWindow_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleInPlaceUIWindow_Release(p) ICOM_CALL (Release,p) +/*** IOleWindow methods ***/ +#define IOleInPlaceUIWindow_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IOleInPlaceUIWindow_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +/*** IOleInPlaceUIWindow methods ***/ +#define IOleInPlaceUIWindow_GetBorder(p,a) ICOM_CALL1(GetBorder,p,a) +#define IOleInPlaceUIWindow_RequestBorderSpace(p,a) ICOM_CALL1(RequestBorderSpace,p,a) +#define IOleInPlaceUIWindow_SetBorderSpace(p,a) ICOM_CALL1(SetBorderSpace,p,a) +#define IOleInPlaceUIWindow_SetActiveObject(p,a,b) ICOM_CALL2(SetActiveObject,p,a,b) + + +/***************************************************************************** + * IOleInPlaceFrame interface + */ +#define ICOM_INTERFACE IOleInPlaceFrame +#define IOleInPlaceFrame_METHODS \ + ICOM_METHOD2 (HRESULT,InsertMenus, HMENU,hemnuShared, LPOLEMENUGROUPWIDTHS,lpMenuWidths) \ + ICOM_METHOD3 (HRESULT,SetMenu, HMENU,hemnuShared, HOLEMENU,holemenu, HWND,hwndActiveObject) \ + ICOM_METHOD1 (HRESULT,RemoveMenus, HMENU,hemnuShared) \ + ICOM_METHOD1 (HRESULT,SetStatusText, LPCOLESTR,pszStatusText) \ + ICOM_METHOD1 (HRESULT,EnableModeless, BOOL,fEnable) \ + ICOM_METHOD2 (HRESULT,TranslateAccelerator, struct tagMSG*,lpmsg, WORD,wID) +#define IOleInPlaceFrame_IMETHODS \ + IOleInPlaceUIWindow_IMETHODS \ + IOleInPlaceFrame_METHODS +ICOM_DEFINE(IOleInPlaceFrame,IOleInPlaceUIWindow) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleInPlaceFrame_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleInPlaceFrame_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleInPlaceFrame_Release(p) ICOM_CALL (Release,p) +/*** IOleWindow methods ***/ +#define IOleInPlaceFrame_GetWindow ICOM_CALL1(GetWindow,p,a) +#define IOleInPlaceFrame_ContextSensitiveHelp ICOM_CALL1(ContextSensitiveHelp,p,a) +/*** IOleInPlaceUIWindow methods ***/ +#define IOleInPlaceFrame_GetBorder ICOM_CALL1(GetBorder,p,a) +#define IOleInPlaceFrame_RequestBorderSpace ICOM_CALL1(RequestBorderSpace,p,a) +#define IOleInPlaceFrame_SetBorderSpace ICOM_CALL1(SetBorderSpace,p,a) +#define IOleInPlaceFrame_SetActiveObject ICOM_CALL2(SetActiveObject,p,a,b) +/*** IOleInPlaceFrame methods ***/ +#define IOleInPlaceFrame_InsertMenus ICOM_CALL2(InsertMenus,p,a,b) +#define IOleInPlaceFrame_SetMenu ICOM_CALL3(SetMenu,p,a,b,c) +#define IOleInPlaceFrame_RemoveMenus ICOM_CALL1(RemoveMenus,p,a) +#define IOleInPlaceFrame_SetStatusText ICOM_CALL1(SetStatusText,p,a) +#define IOleInPlaceFrame_EnableModeless ICOM_CALL1(EnableModeless,p,a) +#define IOleInPlaceFrame_TranslateAccelerator ICOM_CALL2(TranslateAccelerator,p,a,b) + + +/***************************************************************************** + * IOleInPlaceSite interface + */ +#define ICOM_INTERFACE IOleInPlaceSite +#define IOleInPlaceSite_METHODS \ + ICOM_METHOD (HRESULT,CanInPlaceActivate) \ + ICOM_METHOD (HRESULT,OnInPlaceActivate) \ + ICOM_METHOD (HRESULT,OnUIActivate) \ + ICOM_METHOD5(HRESULT,GetWindowContext, IOleInPlaceFrame**,ppFrame, IOleInPlaceUIWindow**,ppDoc, LPRECT,lprcPosRect, LPRECT,lprcClipRect, LPOLEINPLACEFRAMEINFO,lpFrameInfo) \ + ICOM_METHOD1(HRESULT,Scroll, SIZE,scrollExtant) \ + ICOM_METHOD1(HRESULT,OnUIDeactivate, BOOL,fUndoable) \ + ICOM_METHOD (HRESULT,OnInPlaceDeactivate) \ + ICOM_METHOD (HRESULT,DiscardUndoState) \ + ICOM_METHOD (HRESULT,DeactivateAndUndo) \ + ICOM_METHOD1(HRESULT,OnPosRectChange, LPCRECT,lprcPosRect) +#define IOleInPlaceSite_IMETHODS \ + IOleWindow_IMETHODS \ + IOleInPlaceSite_METHODS +ICOM_DEFINE(IOleInPlaceSite,IOleWindow) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleInPlaceSite_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleInPlaceSite_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleInPlaceSite_Release(p) ICOM_CALL (Release,p) +/*** IOleWindow methods ***/ +#define IOleInPlaceSite_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IOleInPlaceSite_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +/*** IOleInPlaceSite methods ***/ +#define IOleInPlaceSite_CanInPlaceActivate(p) ICOM_CALL (CanInPlaceActivate,p) +#define IOleInPlaceSite_OnInPlaceActivate(p) ICOM_CALL (OnInPlaceActivate,p) +#define IOleInPlaceSite_OnUIActivate(p) ICOM_CALL (OnUIActivate,p) +#define IOleInPlaceSite_GetWindowContext(p,a,b,c,d,e) ICOM_CALL5(GetWindowContext,p,a,b,c,d,e) +#define IOleInPlaceSite_Scroll(p,a) ICOM_CALL1(Scroll,p,a) +#define IOleInPlaceSite_OnUIDeactivate(p,a) ICOM_CALL1(OnUIDeactivate,p,a) +#define IOleInPlaceSite_OnInPlaceDeactivate(p) ICOM_CALL (OnInPlaceDeactivate,p) +#define IOleInPlaceSite_DiscardUndoState(p) ICOM_CALL (DiscardUndoState,p) +#define IOleInPlaceSite_DeactivateAndUndo(p) ICOM_CALL (DeactivateAndUndo,p) +#define IOleInPlaceSite_OnPosRectChange(p,a) ICOM_CALL1(OnPosRectChange,p,a) + + +/***************************************************************************** + * IOleClientSite interface + */ +#define ICOM_INTERFACE IOleClientSite +#define IOleClientSite_METHODS \ + ICOM_METHOD (HRESULT,SaveObject) \ + ICOM_METHOD3(HRESULT,GetMoniker, DWORD,dwAssign, DWORD,dwWhichMoniker, IMoniker**,ppmk) \ + ICOM_METHOD1(HRESULT,GetContainer, IOleContainer**,ppContainer) \ + ICOM_METHOD (HRESULT,ShowObject) \ + ICOM_METHOD1(HRESULT,OnShowWindow, BOOL,fShow) \ + ICOM_METHOD (HRESULT,RequestNewObjectLayout) +#define IOleClientSite_IMETHODS \ + IUnknown_IMETHODS \ + IOleClientSite_METHODS +ICOM_DEFINE(IOleClientSite,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleClientSite_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleClientSite_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleClientSite_Release(p) ICOM_CALL (Release,p) +/*** IOleClientSite methods ***/ +#define IOleClientSite_SaveObject(p) ICOM_CALL (SaveObject,p) +#define IOleClientSite_GetMoniker(p,a,b,c) ICOM_CALL3(GetMoniker,p,a,b,c) +#define IOleClientSite_GetContainer(p,a) ICOM_CALL1(GetContainer,p,a) +#define IOleClientSite_ShowObject(p) ICOM_CALL (ShowObject,p) +#define IOleClientSite_OnShowWindow(p,a) ICOM_CALL1(OnShowWindow,p,a) +#define IOleClientSite_RequestNewObjectLayout(p) ICOM_CALL (RequestNewObjectLayout(p) + + +/***************************************************************************** + * IParseDisplayName interface + */ +#define ICOM_INTERFACE IParseDisplayName +#define IParseDisplayName_METHODS \ + ICOM_METHOD4(HRESULT,ParseDisplayName, IBindCtx*,pbc, LPOLESTR,pszDisplayName, ULONG*,pchEaten, IMoniker**,ppmkOut) +#define IParseDisplayName_IMETHODS \ + IUnknown_IMETHODS \ + IParseDisplayName_METHODS +ICOM_DEFINE(IParseDisplayName,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IParseDisplayName_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IParseDisplayName_AddRef(p) ICOM_CALL (AddRef,p) +#define IParseDisplayName_Release(p) ICOM_CALL (Release,p) +/*** IParseDisplayName methods ***/ +#define IParseDisplayName_ParseDisplayName(p,a,b,c,d) ICOM_CALL4(ParseDisplayName,p,a,b,c,d) + + +/***************************************************************************** + * IOleContainer interface + */ +#define ICOM_INTERFACE IOleContainer +#define IOleContainer_METHODS \ + ICOM_METHOD2(HRESULT,EnumObjects, DWORD,grfFlags, IEnumUnknown**,ppenum) \ + ICOM_METHOD1(HRESULT,LockContainer, BOOL,fLock) +#define IOleContainer_IMETHODS \ + IParseDisplayName_IMETHODS \ + IOleContainer_METHODS +ICOM_DEFINE(IOleContainer,IParseDisplayName) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleContainer_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleContainer_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleContainer_Release(p) ICOM_CALL (Release,p) +/*** IParseDisplayName methods ***/ +#define IOleContainer_ParseDisplayName(p,a,b,c,d) ICOM_CALL4(ParseDisplayName,p,a,b,c,d) +/*** IOleClientSite methods ***/ +#define IOleContainer_EnumObjects(p,a,b) ICOM_CALL (EnumObjects,p,a,b) +#define IOleContainer_LockContainer(p,a) ICOM_CALL3(LockContainer,p,a) + + +/***************************************************************************** + * IOleItemContainer interface + */ +#ifdef __WINE__ +#undef GetObject +#endif + +#define ICOM_INTERFACE IOleItemContainer +#define IOleItemContainer_METHODS \ + ICOM_METHOD5(HRESULT,GetObject, LPOLESTR,pszItem, DWORD,dwSpeedNeeded, IBindCtx*,pbc, REFIID,riid, void**,ppvObject) \ + ICOM_METHOD4(HRESULT,GetObjectStorage, LPOLESTR,pszItem, IBindCtx*,pbc, REFIID,riid, void**,ppvStorage) \ + ICOM_METHOD1(HRESULT,IsRunning, LPOLESTR,pszItem) +#define IOleItemContainer_IMETHODS \ + IOleContainer_IMETHODS \ + IOleItemContainer_METHODS +ICOM_DEFINE(IOleItemContainer,IOleContainer) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleItemContainer_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleItemContainer_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleItemContainer_Release(p) ICOM_CALL (Release,p) +/*** IParseDisplayName methods ***/ +#define IOleItemContainer_GetObject(p,a,b,c,d,e) ICOM_CALL5(GetObject,p,a,b,c,d,e) +#define IOleItemContainer_GetObjectStorage(p,a,b,c,d) ICOM_CALL4(GetObjectStorage,p,a,b,c,d) +#define IOleItemContainer_IsRunning(p,a) ICOM_CALL1(IsRunning,p,a) + + +/***************************************************************************** + * IOleItemContainer interface + */ +#define ICOM_INTERFACE IOleLink +#define IOleLink_METHODS \ + ICOM_METHOD1(HRESULT,SetUpdateOptions, DWORD,dwUpdateOpt) \ + ICOM_METHOD1(HRESULT,GetUpdateOptions, DWORD*,pdwUpdateOpt) \ + ICOM_METHOD2(HRESULT,SetSourceMoniker, IMoniker*,pmk, REFCLSID,rclsid) \ + ICOM_METHOD1(HRESULT,GetSourceMoniker, IMoniker**,ppmk) \ + ICOM_METHOD1(HRESULT,SetSourceDisplayName, LPCOLESTR,pszStatusText) \ + ICOM_METHOD1(HRESULT,GetSourceDisplayName, LPOLESTR*,ppszDisplayName) \ + ICOM_METHOD2(HRESULT,BindToSource, DWORD,bindflags, IBindCtx*,pbc) \ + ICOM_METHOD (HRESULT,BindIfRunning) \ + ICOM_METHOD1(HRESULT,GetBoundSource, IUnknown**,ppunk) \ + ICOM_METHOD (HRESULT,UnBindSource) \ + ICOM_METHOD1(HRESULT,Update, IBindCtx*,pbc) +#define IOleLink_IMETHODS \ + IUnknown_IMETHODS \ + IOleLink_METHODS +ICOM_DEFINE(IOleLink,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleLink_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleLink_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleLink_Release(p) ICOM_CALL (Release,p) +/*** IOleLink methods ***/ +#define IOleLink_SetUpdateOptions(p,a) ICOM_CALL1(SetUpdateOptions,p,a) +#define IOleLink_GetUpdateOptions(p,a) ICOM_CALL1(GetUpdateOptions,p,a) +#define IOleLink_SetSourceMoniker(p,a,b) ICOM_CALL2(SetSourceMoniker,p,a,b) +#define IOleLink_GetSourceMoniker(p,a) ICOM_CALL1(GetSourceMoniker,p,a) +#define IOleLink_SetSourceDisplayName(p,a) ICOM_CALL1(SetSourceDisplayName,p,a) +#define IOleLink_GetSourceDisplayName(p,a) ICOM_CALL1(GetSourceDisplayName,p,a) +#define IOleLink_BindToSource(p,a,b) ICOM_CALL2(BindToSource,p,a,b) +#define IOleLink_BindIfRunning(p) ICOM_CALL (BindIfRunning,p) +#define IOleLink_GetBoundSource(p,a) ICOM_CALL1(GetBoundSource,p,a) +#define IOleLink_UnBindSource(p) ICOM_CALL (UnBindSource,p) +#define IOleLink_Update(p,a) ICOM_CALL1(Update,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_INPLACE_H */ + + diff --git a/reactos/include/ole32/obj_marshal.h b/reactos/include/ole32/obj_marshal.h new file mode 100644 index 00000000000..e3656180d89 --- /dev/null +++ b/reactos/include/ole32/obj_marshal.h @@ -0,0 +1,111 @@ +/* + * Defines the COM interfaces and APIs that allow an interface to + * specify a custom marshaling for its objects. + */ + +#ifndef __WINE_WINE_OBJ_MARSHAL_H +#define __WINE_WINE_OBJ_MARSHAL_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IMarshal, 0x00000003L, 0, 0); +typedef struct IMarshal IMarshal,*LPMARSHAL; + +DEFINE_OLEGUID(IID_IStdMarshalInfo, 0x00000018L, 0, 0); +typedef struct IStdMarshalInfo IStdMarshalInfo,*LPSTDMARSHALINFO; + + +/***************************************************************************** + * IMarshal interface + */ +#define ICOM_INTERFACE IMarshal +#define IMarshal_METHODS \ + ICOM_METHOD6(HRESULT,GetUnmarshalClass, REFIID,riid, void*,pv, DWORD,dwDestContext, void*,pvDestContext, DWORD,mshlflags, CLSID*,pCid) \ + ICOM_METHOD6(HRESULT,GetMarshalSizeMax, REFIID,riid, void*,pv, DWORD,dwDestContext, void*,pvDestContext, DWORD,mshlflags, DWORD*,pSize) \ + ICOM_METHOD6(HRESULT,MarshalInterface, IStream*,pStm, REFIID,riid, void*,pv, DWORD,dwDestContext, void*,pvDestContext, DWORD,mshlflags) \ + ICOM_METHOD3(HRESULT,UnmarshalInterface, IStream*,pStm, REFIID,riid, void**,ppv) \ + ICOM_METHOD1(HRESULT,ReleaseMarshalData, IStream*,pStm) \ + ICOM_METHOD1(HRESULT,DisconnectObject, DWORD,dwReserved) +#define IMarshal_IMETHODS \ + IUnknown_IMETHODS \ + IMarshal_METHODS +ICOM_DEFINE(IMarshal,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IMarshal_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IMarshal_AddRef(p) ICOM_CALL (AddRef,p) +#define IMarshal_Release(p) ICOM_CALL (Release,p) +/*** IMarshal methods ***/ +#define IMarshal_GetUnmarshalClass(p,a,b,c,d,e,f) ICOM_CALL6(GetUnmarshalClass,p,a,b,c,d,e,f) +#define IMarshal_GetMarshalSizeMax(p,a,b,c,d,e,f) ICOM_CALL6(GetMarshalSizeMax,p,a,b,c,d,e,f) +#define IMarshal_MarshalInterface(p,a,b,c,d,e,f) ICOM_CALL6(MarshalInterface,p,a,b,c,d,e,f) +#define IMarshal_UnmarshalInterface(p,a,b,c) ICOM_CALL3(UnmarshalInterface,p,a,b,c) +#define IMarshal_ReleaseMarshalData(p,a) ICOM_CALL1(ReleaseMarshalData,p,a) +#define IMarshal_DisconnectObject(p,a) ICOM_CALL1(DisconnectObject,p,a) + + +/***************************************************************************** + * IStdMarshalInfo interface + */ +#define ICOM_INTERFACE IStdMarshalInfo +#define IStdMarshalInfo_METHODS \ + ICOM_METHOD3(HRESULT,GetClassForHandler, DWORD,dwDestContext, void*,pvDestContext, CLSID*,pClsid) +#define IStdMarshalInfo_IMETHODS \ + IUnknown_IMETHODS \ + IStdMarshalInfo_METHODS +ICOM_DEFINE(IStdMarshalInfo,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IStdMarshalInfo_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IStdMarshalInfo_AddRef(p) ICOM_CALL (AddRef,p) +#define IStdMarshalInfo_Release(p) ICOM_CALL (Release,p) +/*** IStdMarshalInfo methods ***/ +#define IStdMarshalInfo_GetClassForHandler(p,a,b,c) ICOM_CALL3(GetClassForHandler,p,a,b,c) + + +/***************************************************************************** + * Additional marshalling API + */ + +/* FIXME: not implemented */ +HRESULT WINAPI CoCreateFreeThreadedMarshaler(LPUNKNOWN punkOuter, LPUNKNOWN* ppunkMarshal); + +/* FIXME: not implemented */ +HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID iid, LPVOID* ppv); + +/* FIXME: not implemented */ +HRESULT WINAPI CoGetMarshalSizeMax(ULONG* pulSize, REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags); + +/* FIXME: not implemented */ +HRESULT WINAPI CoGetStandardMarshal(REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags, LPMARSHAL* ppMarshal); + +/* FIXME: not implemented */ +HRESULT WINAPI CoMarshalHresult(LPSTREAM pstm, HRESULT hresult); + +/* FIXME: not implemented */ +HRESULT WINAPI CoMarshalInterface(LPSTREAM pStm, REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags); + +/* FIXME: not implemented */ +HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, LPUNKNOWN pUnk, LPSTREAM* ppStm); + +/* FIXME: not implemented */ +HRESULT WINAPI CoReleaseMarshalData(LPSTREAM pStm); + +/* FIXME: not implemented */ +HRESULT WINAPI CoUnmarshalHresult(LPSTREAM pstm, HRESULT* phresult); + +/* FIXME: not implemented */ +HRESULT WINAPI CoUnmarshalInterface(LPSTREAM pStm, REFIID riid, LPVOID* ppv); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_MARSHAL_H */ diff --git a/reactos/include/ole32/obj_misc.h b/reactos/include/ole32/obj_misc.h new file mode 100644 index 00000000000..0a312c152fa --- /dev/null +++ b/reactos/include/ole32/obj_misc.h @@ -0,0 +1,192 @@ +/* + * Defines miscellaneous COM interfaces and APIs defined in objidl.h. + * These did not really fit into the other categories, whould have + * required their own specific category or are too rarely used to be + * put in 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_MISC_H +#define __WINE_WINE_OBJ_MISC_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IEnumString, 0x00000101L, 0, 0); +typedef struct IEnumString IEnumString,*LPENUMSTRING; + +DEFINE_OLEGUID(IID_IEnumUnknown, 0x00000100L, 0, 0); +typedef struct IEnumUnknown IEnumUnknown,*LPENUMUNKNOWN; + +DEFINE_OLEGUID(IID_IMallocSpy, 0x0000001dL, 0, 0); +typedef struct IMallocSpy IMallocSpy,*LPMALLOCSPY; + +DEFINE_OLEGUID(IID_IMultiQI, 0x00000020L, 0, 0); +typedef struct IMultiQI IMultiQI,*LPMULTIQI; + + +/***************************************************************************** + * IEnumString interface + */ +#define ICOM_INTERFACE IEnumString +#define IEnumString_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, LPOLESTR*,rgelt, ULONG*,pceltFethed) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT, Clone, IEnumString**, ppenum) +#define IEnumString_IMETHODS \ + IUnknown_IMETHODS \ + IEnumString_METHODS +ICOM_DEFINE(IEnumString,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumString_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumString_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumString_Release(p) ICOM_CALL (Release,p) +/*** IEnumString methods ***/ +#define IEnumString_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumString_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumString_Reset(p) ICOM_CALL (Reset,p) +#define IEnumString_Clone(p,a) ICOM_CALL1(Clone,p,a) + + + +/***************************************************************************** + * IEnumUnknown interface + */ +#define ICOM_INTERFACE IEnumUnknown +#define IEnumUnknown_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, IUnknown**,rgelt, ULONG*,pceltFethed) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumUnknown**,ppenum) +#define IEnumUnknown_IMETHODS \ + IUnknown_IMETHODS \ + IEnumUnknown_METHODS +ICOM_DEFINE(IEnumUnknown,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumUnknown_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumUnknown_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumUnknown_Release(p) ICOM_CALL (Release,p) +/*** IEnumUnknown methods ***/ +#define IEnumUnknown_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumUnknown_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumUnknown_Reset(p) ICOM_CALL (Reset,p) +#define IEnumUnknown_Clone(p,a) ICOM_CALL1(Clone,p,a) + + +/***************************************************************************** + * IMallocSpy interface + */ +#define ICOM_INTERFACE IMallocSpy +#define IMallocSpy_METHODS \ + ICOM_METHOD1 (ULONG,PreAlloc, ULONG,cbRequest) \ + ICOM_VMETHOD1( PostAlloc, void*,pActual) \ + ICOM_METHOD2 (PVOID,PreFree, void*,pRequest, BOOL,fSpyed) \ + ICOM_VMETHOD1( PostFree, BOOL,fSpyed) \ + ICOM_METHOD4 (ULONG,PreRealloc, void*,pRequest, ULONG,cbRequest, void**,ppNewRequest, BOOL,fSpyed) \ + ICOM_METHOD2 (PVOID,PostRealloc, void*,pActual, BOOL,fSpyed) \ + ICOM_METHOD2 (PVOID,PreGetSize, void*,pRequest, BOOL,fSpyed) \ + ICOM_METHOD2 (ULONG,PostGetSize, ULONG,cbActual, BOOL,fSpyed) \ + ICOM_METHOD2 (PVOID,PreDidAlloc, void*,pRequest, BOOL,fSpyed) \ + ICOM_METHOD3 (int, PostDidAlloc, void*,pRequest, BOOL,fSpyed, int,fActual) \ + ICOM_METHOD (int, PreHeapMinimize) \ + ICOM_METHOD (int, PostHeapMinimize) +#define IMallocSpy_IMETHODS \ + IUnknown_IMETHODS \ + IMallocSpy_METHODS +ICOM_DEFINE(IMallocSpy,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IMallocSpy_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IMallocSpy_AddRef(p) ICOM_CALL (AddRef,p) +#define IMallocSpy_Release(p) ICOM_CALL (Release,p) +/*** IMallocSpy methods ***/ +#define IMallocSpy_PreAlloc(p,a) ICOM_CALL1(PreAlloc,p,a) +#define IMallocSpy_PostAlloc(p,a) ICOM_CALL1(PostAlloc,p,a) +#define IMallocSpy_PreFree(p,a,b) ICOM_CALL2(PreFree,p,a,b) +#define IMallocSpy_PostFree(p,a) ICOM_CALL1(PostFree,p,a) +#define IMallocSpy_PreRealloc(p,a,b,c,d) ICOM_CALL4(PreRealloc,p,a,b,c,d) +#define IMallocSpy_PostRealloc(p,a,b) ICOM_CALL2(PostRealloc,p,a,b) +#define IMallocSpy_PreGetSize(p,a,b) ICOM_CALL2(PreGetSize,p,a,b) +#define IMallocSpy_PostGetSize(p,a,b) ICOM_CALL2(PostGetSize,p,a,b) +#define IMallocSpy_PreDidAlloc(p,a,b) ICOM_CALL2(PreDidAlloc,p,a,b) +#define IMallocSpy_PostDidAlloc(p,a,b,c) ICOM_CALL3(PostDidAlloc,p,a,b,c) +#define IMallocSpy_PreHeapMinimize(p) ICOM_CALL (PreHeapMinimize,p) +#define IMallocSpy_PostHeapMinimize(p) ICOM_CALL (PostHeapMinimize,p) + +/* FIXME: not implemented */ +HRESULT WINAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy); + +/* FIXME: not implemented */ +HRESULT WINAPI CoRevokeMallocSpy(void); + +HRESULT WINAPI CoFileTimeNow(FILETIME* lpFileTime); + + +/***************************************************************************** + * IMultiQI interface + */ +typedef struct tagMULTI_QI +{ + const IID* pIID; + IUnknown* pItf; + HRESULT hr; +} MULTI_QI; + +#define ICOM_INTERFACE IMultiQI +#define IMultiQI_METHODS \ + ICOM_METHOD2(HRESULT,QueryMultipleInterfaces, ULONG,cMQIs, MULTI_QI*,pMQIs) +#define IMultiQI_IMETHODS \ + IUnknown_IMETHODS \ + IMultiQI_METHODS +ICOM_DEFINE(IMultiQI,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IMultiQI_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IMultiQI_AddRef(p) ICOM_CALL (AddRef,p) +#define IMultiQI_Release(p) ICOM_CALL (Release,p) +/*** IMultiQI methods ***/ +#define IMultiQI_QueryMultipleInterfaces(p,a,b) ICOM_CALL2(QueryMultipleInterfaces,p,a,b) + + +/***************************************************************************** + * Additional API + */ + +DWORD WINAPI CoBuildVersion(void); + +DWORD WINAPI CoGetCurrentProcess(void); + +/* FIXME: unimplemented */ +HRESULT WINAPI CoGetTreatAsClass(REFCLSID clsidOld, LPCLSID pClsidNew); + +/* FIXME: unimplemented */ +HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew); + +HRESULT WINAPI CoCreateInstance( + REFCLSID rclsid, + LPUNKNOWN pUnkOuter, + DWORD dwClsContext, + REFIID iid, + LPVOID *ppv); + +HRESULT WINAPI CoCreateInstanceEx(REFCLSID rclsid, + LPUNKNOWN pUnkOuter, + DWORD dwClsContext, + COSERVERINFO* pServerInfo, + ULONG cmq, + MULTI_QI* pResults); +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_MISC_H */ diff --git a/reactos/include/ole32/obj_moniker.h b/reactos/include/ole32/obj_moniker.h new file mode 100644 index 00000000000..a08a7e99271 --- /dev/null +++ b/reactos/include/ole32/obj_moniker.h @@ -0,0 +1,350 @@ +/* + * Defines the COM interfaces and APIs related to the moniker functionality. + */ +#ifndef __WINE_WINE_OBJ_MONIKER_H +#define __WINE_WINE_OBJ_MONIKER_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IBindCtx,0xe,0,0); +typedef struct IBindCtx IBindCtx,*LPBINDCTX; +typedef LPBINDCTX LPBC; + +DEFINE_OLEGUID(IID_IClassActivator, 0x00000140L, 0, 0); +typedef struct IClassActivator IClassActivator,*LPCLASSACTIVATOR; + +DEFINE_OLEGUID(IID_IEnumMoniker, 0x00000102L, 0, 0); +typedef struct IEnumMoniker IEnumMoniker,*LPENUMMONIKER; + +DEFINE_OLEGUID(IID_IMoniker, 0x0000000fL, 0, 0); +typedef struct IMoniker IMoniker,*LPMONIKER; + +DEFINE_GUID (IID_IROTData, 0xf29f6bc0L, 0x5021, 0x11ce, 0xaa, 0x15, 0x00, 0x00, 0x69, 0x01, 0x29, 0x3f); +typedef struct IROTData IROTData,*LPROTDATA; + +DEFINE_OLEGUID(IID_IRunnableObject, 0x00000126L, 0, 0); +typedef struct IRunnableObject IRunnableObject,*LPRUNNABLEOBJECT; + +DEFINE_OLEGUID(IID_IRunningObjectTable, 0x00000010L, 0, 0); +typedef struct IRunningObjectTable IRunningObjectTable,*LPRUNNINGOBJECTTABLE; + +DEFINE_GUID( CLSID_FileMoniker,0x00000303,0,0,0xc0,0,0,0,0,0,0,0x46); + +DEFINE_GUID( CLSID_ItemMoniker,0x00000304,0,0,0xc0,0,0,0,0,0,0,0x46); + +DEFINE_GUID( CLSID_AntiMoniker,0x00000305,0,0,0xc0,0,0,0,0,0,0,0x46); + +DEFINE_GUID( CLSID_CompositeMoniker,0x00000309,0,0,0xc0,0,0,0,0,0,0,0x46); + +/********************************************************************************* + * BIND_OPTS and BIND_OPTS2 structures definition + * These structures contain parameters used during a moniker-binding operation. + *********************************************************************************/ +typedef struct tagBIND_OPTS +{ + DWORD cbStruct; + DWORD grfFlags; + DWORD grfMode; + DWORD dwTickCountDeadline; +} BIND_OPTS, * LPBIND_OPTS; + +typedef struct tagBIND_OPTS2 +{ + DWORD cbStruct; + DWORD grfFlags; + DWORD grfMode; + DWORD dwTickCountDeadline; + DWORD dwTrackFlags; + DWORD dwClassContext; + LCID locale; + COSERVERINFO* pServerInfo; +} BIND_OPTS2, * LPBIND_OPTS2; + +/***************************************************************************** + * IBindCtx interface + */ +#define ICOM_INTERFACE IBindCtx +#define IBindCtx_METHODS \ + ICOM_METHOD1 (HRESULT, RegisterObjectBound, IUnknown*,punk) \ + ICOM_METHOD1 (HRESULT, RevokeObjectBound, IUnknown*,punk) \ + ICOM_METHOD (HRESULT, ReleaseBoundObjects) \ + ICOM_METHOD1 (HRESULT, SetBindOptions, LPBIND_OPTS2,pbindopts) \ + ICOM_METHOD1 (HRESULT, GetBindOptions, LPBIND_OPTS2,pbindopts) \ + ICOM_METHOD1 (HRESULT, GetRunningObjectTable,IRunningObjectTable**,pprot) \ + ICOM_METHOD2 (HRESULT, RegisterObjectParam, LPOLESTR,pszkey, IUnknown*,punk) \ + ICOM_METHOD2 (HRESULT, GetObjectParam, LPOLESTR,pszkey, IUnknown**,punk) \ + ICOM_METHOD1 (HRESULT, EnumObjectParam, IEnumString**,ppenum) \ + ICOM_METHOD1 (HRESULT, RevokeObjectParam, LPOLESTR,pszkey) +#define IBindCtx_IMETHODS \ + IUnknown_IMETHODS \ + IBindCtx_METHODS +ICOM_DEFINE(IBindCtx,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IBindCtx_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IBindCtxr_AddRef(p) ICOM_CALL (AddRef,p) +#define IBindCtx_Release(p) ICOM_CALL (Release,p) +/* IBindCtx methods*/ +#define IBindCtx_RegisterObjectBound(p,a) ICOM_CALL1(RegisterObjectBound,p,a) +#define IBindCtx_RevokeObjectBound(p,a) ICOM_CALL1(RevokeObjectBound,p,a) +#define IBindCtx_ReleaseBoundObjects(p) ICOM_CALL (ReleaseBoundObjects,p) +#define IBindCtx_SetBindOptions(p,a) ICOM_CALL1(SetBindOptions,p,a) +#define IBindCtx_GetBindOptions(p,a) ICOM_CALL1(GetBindOptions,p,a) +#define IBindCtx_GetRunningObjectTable(p,a) ICOM_CALL1(GetRunningObjectTable,p,a) +#define IBindCtx_RegisterObjectParam(p,a,b) ICOM_CALL2(RegisterObjectParam,p,a,b) +#define IBindCtx_GetObjectParam(p,a,b) ICOM_CALL2(GetObjectParam,p,a,b) +#define IBindCtx_EnumObjectParam(p,a) ICOM_CALL1(EnumObjectParam,p,a) +#define IBindCtx_RevokeObjectParam(p,a) ICOM_CALL1(RevokeObjectParam,p,a) + +HRESULT WINAPI CreateBindCtx16(DWORD reserved, LPBC* ppbc); +HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC* ppbc); + +/***************************************************************************** + * IClassActivator interface + */ +#define ICOM_INTERFACE IClassActivator +#define IClassActivator_METHODS \ + ICOM_METHOD5(HRESULT,GetClassObject, REFCLSID,rclsid, DWORD,dwClassContext, LCID,locale, REFIID,riid, void**,ppv) +#define IClassActivator_IMETHODS \ + IUnknown_IMETHODS \ + IClassActivator_METHODS +ICOM_DEFINE(IClassActivator,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IClassActivator_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IClassActivator_AddRef(p) ICOM_CALL (AddRef,p) +#define IClassActivator_Release(p) ICOM_CALL (Release,p) +/*** IClassActivator methods ***/ +#define IClassActivator_GetClassObject(p,a,b,c,d,e) ICOM_CALL5(GetClassObject,p,a,b,c,d,e) + + +/***************************************************************************** + * IEnumMoniker interface + */ +#define ICOM_INTERFACE IEnumMoniker +#define IEnumMoniker_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, IMoniker**,rgelt, ULONG*,pceltFethed) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumMoniker**,ppenum) +#define IEnumMoniker_IMETHODS \ + IUnknown_IMETHODS \ + IEnumMoniker_METHODS +ICOM_DEFINE(IEnumMoniker,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumMoniker_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumMoniker_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumMoniker_Release(p) ICOM_CALL (Release,p) +/*** IEnumMoniker methods ***/ +#define IEnumMoniker_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumMoniker_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumMoniker_Reset(p) ICOM_CALL (Reset,p) +#define IEnumMoniker_Clone(p,a) ICOM_CALL1(Clone,p,a) + +/***************************************************************************** + * IMoniker interface + */ + +typedef enum tagMKSYS +{ + MKSYS_NONE = 0, + MKSYS_GENERICCOMPOSITE = 1, + MKSYS_FILEMONIKER = 2, + MKSYS_ANTIMONIKER = 3, + MKSYS_ITEMMONIKER = 4, + MKSYS_POINTERMONIKER = 5, + MKSYS_CLASSMONIKER = 7 +} MKSYS; + +typedef enum tagMKREDUCE +{ + MKRREDUCE_ONE = 3 << 16, + MKRREDUCE_TOUSER = 2 << 16, + MKRREDUCE_THROUGHUSER = 1 << 16, + MKRREDUCE_ALL = 0 +} MKRREDUCE; + +#define ICOM_INTERFACE IMoniker +#define IMoniker_METHODS \ + ICOM_METHOD4(HRESULT,BindToObject, IBindCtx*,pbc, IMoniker*,pmkToLeft, REFIID,riidResult, void**,ppvResult) \ + ICOM_METHOD4(HRESULT,BindToStorage, IBindCtx*,pbc, IMoniker*,pmkToLeft, REFIID,riid, void**,ppvObj) \ + ICOM_METHOD4(HRESULT,Reduce, IBindCtx*,pbc, DWORD,dwReduceHowFar, IMoniker**,ppmkToLeft, IMoniker**,ppmkReduced) \ + ICOM_METHOD3(HRESULT,ComposeWith, IMoniker*,pmkRight, BOOL,fOnlyIfNotGeneric, IMoniker**,ppmkComposite) \ + ICOM_METHOD2(HRESULT,Enum, BOOL,fForward, IEnumMoniker**,ppenumMoniker) \ + ICOM_METHOD1(HRESULT,IsEqual, IMoniker*,pmkOtherMoniker) \ + ICOM_METHOD1(HRESULT,Hash, DWORD*,pdwHash) \ + ICOM_METHOD3(HRESULT,IsRunning, IBindCtx*,pbc, IMoniker*,pmkToLeft, IMoniker*,pmkNewlyRunning) \ + ICOM_METHOD3(HRESULT,GetTimeOfLastChange, IBindCtx*,pbc, IMoniker*,pmkToLeft, FILETIME*,pFileTime) \ + ICOM_METHOD1(HRESULT,Inverse, IMoniker**,ppmk) \ + ICOM_METHOD2(HRESULT,CommonPrefixWith, IMoniker*,pmkOtherMoniker, IMoniker**,ppmkPrefix) \ + ICOM_METHOD2(HRESULT,RelativePathTo, IMoniker*,pmkOther, IMoniker**,ppmkRelPath) \ + ICOM_METHOD3(HRESULT,GetDisplayName, IBindCtx*,pbc, IMoniker*,pmkToLeft, LPOLESTR*,ppszDisplayName) \ + ICOM_METHOD5(HRESULT,ParseDisplayName, IBindCtx*,pbc, IMoniker*,pmkToLeft, LPOLESTR,pszDisplayName, ULONG*,pchEaten, IMoniker**,ppmkOut) \ + ICOM_METHOD1(HRESULT,IsSystemMoniker, DWORD*,pdwMksys) +#define IMoniker_IMETHODS \ + IPersistStream_IMETHODS \ + IMoniker_METHODS +ICOM_DEFINE(IMoniker,IPersistStream) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IMoniker_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IMoniker_AddRef(p) ICOM_CALL (AddRef,p) +#define IMoniker_Release(p) ICOM_CALL (Release,p) + +/*** IPersist methods ***/ +#define IMoniker_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) +/*** IPersistStream methods ***/ +#define IMoniker_IsDirty(p) ICOM_CALL (IsDirty,p) +#define IMoniker_Load(p,a) ICOM_CALL1(Load,p,a) +#define IMoniker_Save(p,a,b) ICOM_CALL2(Save,p,a,b) +#define IMoniker_GetSizeMax(p,a) ICOM_CALL1(GetSizeMax,p,a) +/*** IMoniker methods ***/ +#define IMoniker_BindToObject(p,a,b,c,d) ICOM_CALL4(BindToObject,p,a,b,c,d) +#define IMoniker_BindToStorage(p,a,b,c,d) ICOM_CALL4(BindToStorage,p,a,b,c,d) +#define IMoniker_Reduce(p,a,b,c,d) ICOM_CALL4(Reduce,p,a,b,c,d) +#define IMoniker_ComposeWith(p,a,b,c) ICOM_CALL3(ComposeWith,p,a,b,c) +#define IMoniker_Enum(p,a,b) ICOM_CALL2(Enum,p,a,b) +#define IMoniker_IsEqual(p,a) ICOM_CALL1(IsEqual,p,a) +#define IMoniker_Hash(p,a) ICOM_CALL1(Hash,p,a) +#define IMoniker_IsRunning(p,a,b,c) ICOM_CALL3(IsRunning,p,a,b,c) +#define IMoniker_GetTimeOfLastChange(p,a,b,c) ICOM_CALL3(GetTimeOfLastChange,p,a,b,c) +#define IMoniker_Inverse(p,a) ICOM_CALL1(Inverse,p,a) +#define IMoniker_CommonPrefixWith(p,a,b) ICOM_CALL2(CommonPrefixWith,p,a,b) +#define IMoniker_RelativePathTo(p,a,b) ICOM_CALL2(RelativePathTo,p,a,b) +#define IMoniker_GetDisplayName(p,a,b,c) ICOM_CALL3(GetDisplayName,p,a,b,c) +#define IMoniker_ParseDisplayName(p,a,b,c,d,e) ICOM_CALL5(ParseDisplayName,p,a,b,c,d,e) +#define IMoniker_IsSystemMoniker(p,a) ICOM_CALL1(IsSystemMoniker,p,a) + +HRESULT WINAPI CreateFileMoniker16(LPCOLESTR16 lpszPathName, LPMONIKER* ppmk); +HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER* ppmk); + +HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim, LPCOLESTR lpszItem, LPMONIKER* ppmk); +HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim, LPCOLESTR lpszItem, LPMONIKER* ppmk); + +HRESULT WINAPI CreateAntiMoniker(LPMONIKER * ppmk); + +HRESULT WINAPI CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest, LPMONIKER* ppmkComposite); + +/* FIXME: not implemented */ +HRESULT WINAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID iidResult, LPVOID* ppvResult); + +/* FIXME: not implemented */ +HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, LPMONIKER* ppmk); + +/* FIXME: not implemented */ +HRESULT WINAPI CreatePointerMoniker(LPUNKNOWN punk, LPMONIKER* ppmk); + +/* FIXME: not implemented */ +HRESULT WINAPI MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon); +/***************************************************************************** + * IROTData interface + */ +#define ICOM_INTERFACE IROTData +#define IROTData_METHODS \ + ICOM_METHOD3(HRESULT,GetComparisonData, BYTE*,pbData, ULONG,cbMax, ULONG*,pcbData) +#define IROTData_IMETHODS \ + IUnknown_IMETHODS \ + IROTData_METHODS +ICOM_DEFINE(IROTData,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IROTData_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IROTData_AddRef(p) ICOM_CALL (AddRef,p) +#define IROTData_Release(p) ICOM_CALL (Release,p) +/*** IROTData methods ***/ +#define IROTData_GetComparisonData(p,a,b,c) ICOM_CALL3(GetComparisonData,p,a,b,c) + +#define ICOM_THIS_From_IROTData(class, name) class* This = (class*)(((char*)name)-sizeof(void*)) + +/***************************************************************************** + * IRunnableObject interface + */ +#define ICOM_INTERFACE IRunnableObject +#define IRunnableObject_METHODS \ + ICOM_METHOD1(HRESULT,GetRunningClass, LPCLSID,lpClsid) \ + ICOM_METHOD1(HRESULT,Run, IBindCtx*,pbc) \ + ICOM_METHOD (BOOL,IsRunning) \ + ICOM_METHOD2(HRESULT,LockRunning, BOOL,fLock, BOOL,fLastUnlockCloses) \ + ICOM_METHOD1(HRESULT,SetContainedObject, BOOL,fContained) +#define IRunnableObject_IMETHODS \ + IUnknown_IMETHODS \ + IRunnableObject_METHODS +ICOM_DEFINE(IRunnableObject,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IRunnableObject_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IRunnableObject_AddRef(p) ICOM_CALL (AddRef,p) +#define IRunnableObject_Release(p) ICOM_CALL (Release,p) +/*** IRunnableObject methods ***/ +#define IRunnableObject_GetRunningClass(p,a) ICOM_CALL1(GetRunningClass,p,a) +#define IRunnableObject_Run(p,a) ICOM_CALL1(Run,p,a) +#define IRunnableObject_IsRunning(p) ICOM_CALL (IsRunning,p) +#define IRunnableObject_LockRunning(p,a,b) ICOM_CALL2(LockRunning,p,a,b) +#define IRunnableObject_SetContainedObject(p,a) ICOM_CALL1(SetContainedObject,p,a) + + +/***************************************************************************** + * IRunningObjectTable interface + */ +#ifdef __WINE__ +#undef GetObject +#endif + +#define ICOM_INTERFACE IRunningObjectTable +#define IRunningObjectTable_METHODS \ + ICOM_METHOD4(HRESULT,Register, DWORD,grfFlags, IUnknown*,punkObject, IMoniker*,pmkObjectName, DWORD*,pdwRegister) \ + ICOM_METHOD1(HRESULT,Revoke, DWORD,dwRegister) \ + ICOM_METHOD1(HRESULT,IsRunning, IMoniker*,pmkObjectName) \ + ICOM_METHOD2(HRESULT,GetObject, IMoniker*,pmkObjectName, IUnknown**,ppunkObject) \ + ICOM_METHOD2(HRESULT,NoteChangeTime, DWORD,dwRegister, FILETIME*,pfiletime) \ + ICOM_METHOD2(HRESULT,GetTimeOfLastChange, IMoniker*,pmkObjectName, FILETIME*,pfiletime) \ + ICOM_METHOD1(HRESULT,EnumRunning, IEnumMoniker**,ppenumMoniker) +#define IRunningObjectTable_IMETHODS \ + IUnknown_IMETHODS \ + IRunningObjectTable_METHODS +ICOM_DEFINE(IRunningObjectTable,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IRunningObjectTable_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IRunningObjectTable_AddRef(p) ICOM_CALL (AddRef,p) +#define IRunningObjectTable_Release(p) ICOM_CALL (Release,p) +/*** IRunningObjectTable methods ***/ +#define IRunningObjectTable_Register(p,a,b,c,d) ICOM_CALL4(Register,p,a,b,c,d) +#define IRunningObjectTable_Revoke(p,a) ICOM_CALL1(Revoke,p,a) +#define IRunningObjectTable_IsRunning(p,a) ICOM_CALL1(IsRunning,p,a) +#define IRunningObjectTable_GetObject(p,a,b) ICOM_CALL2(GetObject,p,a,b) +#define IRunningObjectTable_NoteChangeTime(p,a,b) ICOM_CALL2(NoteChangeTime,p,a,b) +#define IRunningObjectTable_GetTimeOfLastChange(p,a,b) ICOM_CALL2(GetTimeOfLastChange,p,a,b) +#define IRunningObjectTable_EnumRunning(p,a) ICOM_CALL1(EnumRunning,p,a) + +HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot); +HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot); + +/***************************************************************************** + * Additional API + */ + +/* FIXME: not implemented */ +HRESULT WINAPI CoGetInstanceFromFile(COSERVERINFO* pServerInfo, CLSID* pClsid, IUnknown* punkOuter, DWORD dwClsCtx, DWORD grfMode, OLECHAR* pwszName, DWORD dwCount, MULTI_QI* pResults); + +/* FIXME: not implemented */ +HRESULT WINAPI CoGetInstanceFromIStorage(COSERVERINFO* pServerInfo, CLSID* pClsid, IUnknown* punkOuter, DWORD dwClsCtx, IStorage* pstg, DWORD dwCount, MULTI_QI* pResults); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_MONIKER_H */ diff --git a/reactos/include/ole32/obj_oleaut.h b/reactos/include/ole32/obj_oleaut.h new file mode 100644 index 00000000000..04c5c0cd205 --- /dev/null +++ b/reactos/include/ole32/obj_oleaut.h @@ -0,0 +1,824 @@ +/* + * Defines the COM interfaces and APIs related to OLE automation support. + */ + +#ifndef __WINE_WINE_OBJ_OLEAUT_H +#define __WINE_WINE_OBJ_OLEAUT_H + + +DEFINE_OLEGUID(IID_StdOle, 0x00020430,0,0); + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IDispatch, 0x00020400,0,0); +typedef struct IDispatch IDispatch,*LPDISPATCH; + +DEFINE_OLEGUID(IID_ITypeInfo, 0x00020401,0,0); +typedef struct ITypeInfo ITypeInfo,*LPTYPEINFO; + +DEFINE_OLEGUID(IID_ITypeLib, 0x00020402,0,0); +typedef struct ITypeLib ITypeLib,*LPTYPELIB; + +DEFINE_OLEGUID(IID_ITypeComp, 0x00020403,0,0); +typedef struct ITypeComp ITypeComp,*LPTYPECOMP; + +DEFINE_OLEGUID(IID_IEnumVARIANT, 0x00020404,0,0); +typedef struct IEnumVARIANT IEnumVARIANT,*LPENUMVARIANT; + +DEFINE_OLEGUID(IID_ICreateTypeInfo, 0x00020405,0,0); +typedef struct ICreateTypeInfo ICreateTypeInfo,*LPCREATETYPEINFO; + +DEFINE_OLEGUID(IID_ICreateTypeLib, 0x00020406,0,0); +typedef struct ICreateTypeLib ICreateTypeLib,*LPCREATETYPELIB; + +DEFINE_OLEGUID(IID_ICreateTypeInfo2,0x0002040E,0,0); +typedef struct ICreateTypeInfo2 ICreateTypeInfo2,*LPCREATETYPEINFO2; + +DEFINE_OLEGUID(IID_ICreateTypeLib2, 0x0002040F,0,0); +typedef struct ICreateTypeLib2 ICreateTypeLib2,*LPCREATETYPELIB2; + +DEFINE_OLEGUID(IID_ITypeChangeEvents,0x00020410,0,0); +typedef struct ITypeChangeEvents ITypeChangeEvents,*LPTYPECHANGEEVENTS; + +DEFINE_OLEGUID(IID_ITypeLib2, 0x00020411,0,0); +typedef struct ITypeLib2 ITypeLib2,*LPTYPELIB2; + +DEFINE_OLEGUID(IID_ITypeInfo2, 0x00020412,0,0); +typedef struct ITypeInfo2 ITypeInfo2,*LPTYPEINFO2; + +/***************************************************************************** + * Automation data types + */ + +/***************************************************************** + * SafeArray defines and structs + */ + +#define FADF_AUTO ( 0x1 ) +#define FADF_STATIC ( 0x2 ) +#define FADF_EMBEDDED ( 0x4 ) +#define FADF_FIXEDSIZE ( 0x10 ) +#define FADF_RECORD ( 0x20 ) +#define FADF_HAVEIID ( 0x40 ) +#define FADF_HAVEVARTYPE ( 0x80 ) +#define FADF_BSTR ( 0x100 ) +#define FADF_UNKNOWN ( 0x200 ) +#define FADF_DISPATCH ( 0x400 ) +#define FADF_VARIANT ( 0x800 ) +#define FADF_RESERVED ( 0xf008 ) + +/* Undocumented flags */ +#define FADF_CREATEVECTOR ( 0x2000 ) /* set when the safe array is created using SafeArrayCreateVector */ + + +typedef struct tagSAFEARRAYBOUND +{ + ULONG cElements; /* Number of elements in dimension */ + LONG lLbound; /* Lower bound of dimension */ +} SAFEARRAYBOUND; + +typedef struct tagSAFEARRAY +{ + USHORT cDims; /* Count of array dimension */ + USHORT fFeatures; /* Flags describing the array */ + ULONG cbElements; /* Size of each element */ + ULONG cLocks; /* Number of lock on array */ + PVOID pvData; /* Pointer to data valid when cLocks > 0 */ + SAFEARRAYBOUND rgsabound[ 1 ]; /* One bound for each dimension */ +} SAFEARRAY, *LPSAFEARRAY; + +typedef enum tagCALLCONV { + CC_CDECL = 1, + CC_MSCPASCAL = CC_CDECL + 1, + CC_PASCAL = CC_MSCPASCAL, + CC_MACPASCAL = CC_PASCAL + 1, + CC_STDCALL = CC_MACPASCAL + 1, + CC_RESERVED = CC_STDCALL + 1, + CC_SYSCALL = CC_RESERVED + 1, + CC_MPWCDECL = CC_SYSCALL + 1, + CC_MPWPASCAL = CC_MPWCDECL + 1, + CC_MAX = CC_MPWPASCAL + 1 +} CALLCONV; + +typedef CY CURRENCY; + +/* + * Declarations of the VARIANT structure and the VARIANT APIs. + */ +/* S_OK : Success. + * DISP_E_BADVARTYPE : The variant type vt in not a valid type of variant. + * DISP_E_OVERFLOW : The data pointed to by pvarSrc does not fit in the destination type. + * DISP_E_TYPEMISMATCH : The variant type vt is not a valid type of variant. + * E_INVALIDARG : One argument is invalid. + * * E_OUTOFMEMORY : Memory could not be allocated for the conversion. + * DISP_E_ARRAYISLOCKED : The variant contains an array that is locked. + */ + +typedef struct tagVARIANT VARIANT, *LPVARIANT; +typedef struct tagVARIANT VARIANTARG, *LPVARIANTARG; + +struct tagVARIANT { + VARTYPE vt; + WORD wReserved1; + WORD wReserved2; + WORD wReserved3; + union /* DUMMYUNIONNAME */ + { + /* By value. */ + CHAR cVal; + USHORT uiVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + BYTE bVal; + short iVal; + long lVal; + float fltVal; + double dblVal; + VARIANT_BOOL boolVal; + SCODE scode; + DATE date; + BSTR bstrVal; + CY cyVal; + /* FIXME: This is not supposed to be at this level + * See bug #181 in bugzilla + * DECIMAL decVal; + */ + IUnknown* punkVal; + IDispatch* pdispVal; + SAFEARRAY* parray; + + /* By reference */ + CHAR* pcVal; + USHORT* puiVal; + ULONG* pulVal; + INT* pintVal; + UINT* puintVal; + BYTE* pbVal; + short* piVal; + long* plVal; + float* pfltVal; + double* pdblVal; + VARIANT_BOOL* pboolVal; + SCODE* pscode; + DATE* pdate; + BSTR* pbstrVal; + VARIANT* pvarVal; + PVOID byref; + CY* pcyVal; + DECIMAL* pdecVal; + IUnknown** ppunkVal; + IDispatch** ppdispVal; + SAFEARRAY** pparray; + } DUMMYUNIONNAME; +}; + + +typedef LONG DISPID; +typedef DWORD HREFTYPE; +typedef DISPID MEMBERID; + +#define DISPATCH_METHOD 0x1 +#define DISPATCH_PROPERTYGET 0x2 +#define DISPATCH_PROPERTYPUT 0x4 +#define DISPATCH_PROPERTYPUTREF 0x8 + +#define DISPID_UNKNOWN ( -1 ) +#define DISPID_VALUE ( 0 ) +#define DISPID_PROPERTYPUT ( -3 ) +#define DISPID_NEWENUM ( -4 ) +#define DISPID_EVALUATE ( -5 ) +#define DISPID_CONSTRUCTOR ( -6 ) +#define DISPID_DESTRUCTOR ( -7 ) +#define DISPID_COLLECT ( -8 ) + +#define MEMBERID_NIL DISPID_UNKNOWN + +#define IMPLTYPEFLAG_FDEFAULT (0x1) +#define IMPLTYPEFLAG_FSOURCE (0x2) +#define IMPLTYPEFLAG_FRESTRICTED (0x4) +#define IMPLTYPEFLAG_FDEFAULTVTABLE (0x8) + +typedef struct tagDISPPARAMS +{ + VARIANTARG* rgvarg; + DISPID* rgdispidNamedArgs; + UINT cArgs; + UINT cNamedArgs; +} DISPPARAMS; + +typedef struct tagEXCEPINFO +{ + WORD wCode; + WORD wReserved; + BSTR bstrSource; + BSTR bstrDescription; + BSTR bstrHelpFile; + DWORD dwHelpContext; + PVOID pvReserved; + HRESULT __stdcall (*pfnDeferredFillIn)(struct tagEXCEPINFO *); + SCODE scode; +} EXCEPINFO, * LPEXCEPINFO; + +typedef struct tagIDLDESC +{ + ULONG dwReserved; + USHORT wIDLFlags; +} IDLDESC; + +typedef struct tagPARAMDESCEX +{ + ULONG cBytes; + VARIANTARG varDefaultValue; +} PARAMDESCEX, *LPPARAMDESCEX; + +typedef struct tagPARAMDESC +{ + LPPARAMDESCEX pparamdescex; + USHORT wParamFlags; +} PARAMDESC; + +#define PARAMFLAG_NONE (0x00) +#define PARAMFLAG_FIN (0x01) +#define PARAMFLAG_FOUT (0x02) +#define PARAMFLAG_FLCID (0x04) +#define PARAMFLAG_FRETVAL (0x08) +#define PARAMFLAG_FOPT (0x10) +#define PARAMFLAG_FHASDEFAULT (0x20) + + +typedef struct tagTYPEDESC +{ + union { + struct tagTYPEDESC *lptdesc; + struct tagARRAYDESC *lpadesc; + HREFTYPE hreftype; + } DUMMYUNIONNAME; + VARTYPE vt; +} TYPEDESC; + +typedef struct tagELEMDESC +{ + TYPEDESC tdesc; + union { + IDLDESC idldesc; + PARAMDESC paramdesc; + } DUMMYUNIONNAME; +} ELEMDESC, *LPELEMDESC; + +typedef enum tagTYPEKIND +{ + TKIND_ENUM = 0, + TKIND_RECORD = 1, + TKIND_MODULE = 2, + TKIND_INTERFACE = 3, + TKIND_DISPATCH = 4, + TKIND_COCLASS = 5, + TKIND_ALIAS = 6, + TKIND_UNION = 7, + TKIND_MAX = 8 +} TYPEKIND; + +typedef struct tagTYPEATTR +{ + GUID guid; + LCID lcid; + DWORD dwReserved; + MEMBERID memidConstructor; + MEMBERID memidDestructor; + LPOLESTR lpstrSchema; + ULONG cbSizeInstance; + TYPEKIND typekind; + WORD cFuncs; + WORD cVars; + WORD cImplTypes; + WORD cbSizeVft; + WORD cbAlignment; + WORD wTypeFlags; + WORD wMajorVerNum; + WORD wMinorVerNum; + TYPEDESC tdescAlias; + IDLDESC idldescType; +} TYPEATTR, *LPTYPEATTR; + +#define TYPEFLAG_NONE (0x00) +#define TYPEFLAG_FAPPOBJECT (0x01) +#define TYPEFLAG_FCANCREATE (0x02) +#define TYPEFLAG_FLICENSED (0x04) +#define TYPEFLAG_FPREDECLID (0x08) +#define TYPEFLAG_FHIDDEN (0x0f) +#define TYPEFLAG_FCONTROL (0x20) +#define TYPEFLAG_FDUAL (0x40) +#define TYPEFLAG_FNONEXTENSIBLE (0x80) +#define TYPEFLAG_FOLEAUTOMATION (0x100) +#define TYPEFLAG_FRESTRICTED (0x200) +#define TYPEFLAG_FAGGREGATABLE (0x400) +#define TYPEFLAG_FREPLACEABLE (0x800) +#define TYPEFLAG_FDISPATCHABLE (0x1000) +#define TYPEFLAG_FREVERSEBIND (0x2000) +#define TYPEFLAG_FPROXY (0x4000) +#define TYPEFLAG_DEFAULTFILTER (0x8000) +#define TYPEFLAG_COCLASSATTRIBUTES (0x63f) +#define TYPEFLAG_INTERFACEATTRIBUTES (0x7bd0) +#define TYPEFLAG_DISPATCHATTRIBUTES (0x5a90) +#define TYPEFLAG_ALIASATTRIBUTES (0x210) +#define TYPEFLAG_MODULEATTRIBUTES (0x210) +#define TYPEFLAG_ENUMATTRIBUTES (0x210) +#define TYPEFLAG_RECORDATTRIBUTES (0x210) +#define TYPEFLAG_UNIONATTRIBUTES (0x210) + +typedef struct tagARRAYDESC +{ + TYPEDESC tdescElem; + USHORT cDims; + SAFEARRAYBOUND rgbounds[1]; +} ARRAYDESC; + +typedef enum tagFUNCKIND +{ + FUNC_VIRTUAL = 0, + FUNC_PUREVIRTUAL = 1, + FUNC_NONVIRTUAL = 2, + FUNC_STATIC = 3, + FUNC_DISPATCH = 4 +} FUNCKIND; + +typedef enum tagINVOKEKIND +{ + INVOKE_FUNC = 1, + INVOKE_PROPERTYGET = 2, + INVOKE_PROPERTYPUT = 3, + INVOKE_PROPERTYPUTREF = 4 +} INVOKEKIND; + +typedef struct tagFUNCDESC +{ + MEMBERID memid; + SCODE *lprgscode; + ELEMDESC *lprgelemdescParam; + FUNCKIND funckind; + INVOKEKIND invkind; + CALLCONV callconv; + SHORT cParams; + SHORT cParamsOpt; + SHORT oVft; + SHORT cScodes; + ELEMDESC elemdescFunc; + WORD wFuncFlags; +} FUNCDESC, *LPFUNCDESC; + +typedef enum tagVARKIND +{ + VAR_PERINSTANCE = 0, + VAR_STATIC = 1, + VAR_CONST = 2, + VAR_DISPATCH = 3 +} VARKIND; + +typedef struct tagVARDESC +{ + MEMBERID memid; + LPOLESTR lpstrSchema; + union { + ULONG oInst; + VARIANT *lpvarValue; + } DUMMYUNIONNAME; + ELEMDESC elemdescVar; + WORD wVarFlags; + VARKIND varkind; +} VARDESC, *LPVARDESC; + +typedef enum tagSYSKIND +{ + SYS_WIN16 = 0, + SYS_WIN32 = 1, + SYS_MAC = 2 +} SYSKIND; + +typedef enum tagLIBFLAGS +{ + LIBFLAG_FRESTRICTED = 0x1, + LIBFLAG_FCONTROL = 0x2, + LIBFLAG_FHIDDEN = 0x4, + LIBFLAG_FHASDISKIMAGE = 0x8 +} LIBFLAGS; + +typedef struct tagTLIBATTR +{ + GUID guid; + LCID lcid; + SYSKIND syskind; + WORD wMajorVerNum; + WORD wMinorVerNum; + WORD wLibFlags; +} TLIBATTR, *LPTLIBATTR; + +typedef enum tagDESCKIND +{ + DESCKIND_NONE = 0, + DESCKIND_FUNCDESC = 1, + DESCKIND_VARDESC = 2, + DESCKIND_TYPECOMP = 3, + DESCKIND_IMPLICITAPPOBJ = 4, + DESCKIND_MAX = 6 +} DESCKIND; + +typedef union tagBINDPTR +{ + FUNCDESC *lpfuncdesc; + VARDESC *lpvardesc; + ITypeComp *lptcomp; +} BINDPTR, *LPBINDPTR; + +typedef enum tagVARFLAGS +{ + VARFLAG_FREADONLY = 0x1, + VARFLAG_FSOURCE = 0x2, + VARFLAG_FBINDABLE = 0x4, + VARFLAG_FREQUESTEDIT = 0x8, + VARFLAG_FDISPLAYBIND = 0x10, + VARFLAG_FDEFAULTBIND = 0x20, + VARFLAG_FHIDDEN = 0x40, + VARFLAG_FRESTRICTED = 0x80, + VARFLAG_FDEFAULTCOLLELEM = 0x100, + VARFLAG_FUIDEFAULT = 0x200, + VARFLAG_FNONBROWSABLE = 0x400, + VARFLAG_FREPLACEABLE = 0x800, + VARFLAG_FIMMEDIATEBIND = 0x1000 +} VARFLAGS; + + +/* + * Data types for Variants. + */ + +enum VARENUM { + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_PTR = 26, + VT_SAFEARRAY = 27, + VT_CARRAY = 28, + VT_USERDEFINED = 29, + VT_LPSTR = 30, + VT_LPWSTR = 31, + VT_RECORD = 36, + VT_FILETIME = 64, + VT_BLOB = 65, + VT_STREAM = 66, + VT_STORAGE = 67, + VT_STREAMED_OBJECT = 68, + VT_STORED_OBJECT = 69, + VT_BLOB_OBJECT = 70, + VT_CF = 71, + VT_CLSID = 72, + VT_VECTOR = 0x1000, + VT_ARRAY = 0x2000, + VT_BYREF = 0x4000, + VT_RESERVED = 0x8000, + VT_ILLEGAL = 0xffff, + VT_ILLEGALMASKED = 0xfff, + VT_TYPEMASK = 0xfff +}; + +/* the largest valide type + */ +#define VT_MAXVALIDTYPE VT_CLSID + + +/* + * Declarations of the VARIANT structure and the VARIANT APIs. + */ + +/* S_OK : Success. + * DISP_E_BADVARTYPE : The variant type vt in not a valid type of variant. + * DISP_E_OVERFLOW : The data pointed to by pvarSrc does not fit in the destination type. + * DISP_E_TYPEMISMATCH : The variant type vt is not a valid type of variant. + * E_INVALIDARG : One argument is invalid. + * E_OUTOFMEMORY : Memory could not be allocated for the conversion. + * DISP_E_ARRAYISLOCKED : The variant contains an array that is locked. + */ + + +typedef struct tagCUSTDATAITEM { + GUID guid; + VARIANTARG varValue; +} CUSTDATAITEM, *LPCUSTDATAITEM; + +typedef struct tagCUSTDATA { + INT cCustData; + LPCUSTDATAITEM prgCustData; /* count cCustdata */ +} CUSTDATA, *LPCUSTDATA; + + + +/***************************************************************************** + * IDispatch interface + */ +#define ICOM_INTERFACE IDispatch +#define IDispatch_METHODS \ + ICOM_METHOD1(HRESULT, GetTypeInfoCount, UINT*, pctinfo) \ + ICOM_METHOD3(HRESULT, GetTypeInfo, UINT, iTInfo, LCID, lcid, ITypeInfo**, ppTInfo) \ + ICOM_METHOD5(HRESULT, GetIDsOfNames, REFIID, riid, LPOLESTR*, rgszNames, UINT, cNames, LCID, lcid, DISPID*, rgDispId) \ + ICOM_METHOD8(HRESULT, Invoke, DISPID, dispIdMember, REFIID, riid, LCID, lcid, WORD, wFlags, DISPPARAMS*, pDispParams, VARIANT*, pVarResult, EXCEPINFO*, pExepInfo, UINT*, puArgErr) +#define IDispatch_IMETHODS \ + IUnknown_IMETHODS \ + IDispatch_METHODS +ICOM_DEFINE(IDispatch,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IDispatch_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDispatch_AddRef(p) ICOM_CALL (AddRef,p) +#define IDispatch_Release(p) ICOM_CALL (Release,p) +/*** IDispatch methods ***/ +#define IDispatch_GetTypeInfoCount(p,a) ICOM_CALL1 (GetTypeInfoCount,p,a) +#define IDispatch_GetTypeInfo(p,a,b,c) ICOM_CALL3 (GetTypeInfo,p,a,b,c) +#define IDispatch_GetIDsOfNames(p,a,b,c,d,e) ICOM_CALL5 (GetIDsOfNames,p,a,b,c,d,e) +#define IDispatch_Invoke(p,a,b,c,d,e,f,g,h) ICOM_CALL8 (Invoke,p,a,b,c,d,e,f,g,h) + + +/***************************************************************************** + * ITypeInfo interface + */ +#define ICOM_INTERFACE ITypeInfo +#define ITypeInfo_METHODS \ + ICOM_METHOD1(HRESULT,GetTypeAttr, TYPEATTR**,ppTypeAttr) \ + ICOM_METHOD1(HRESULT,GetTypeComp, ITypeComp**,ppTComp) \ + ICOM_METHOD2(HRESULT,GetFuncDesc, UINT,index, FUNCDESC**,ppFuncDesc) \ + ICOM_METHOD2(HRESULT,GetVarDesc, UINT,index, VARDESC**,ppVarDesc) \ + ICOM_METHOD4(HRESULT,GetNames, MEMBERID,memid, BSTR*,rgBstrNames, UINT,cMaxNames, UINT*,pcNames) \ + ICOM_METHOD2(HRESULT,GetRefTypeOfImplType, UINT,index, HREFTYPE*, pRefType) \ + ICOM_METHOD2(HRESULT,GetImplTypeFlags, UINT,index, INT*,pImplTypeFlags)\ + ICOM_METHOD3(HRESULT,GetIDsOfNames, LPOLESTR*,rgszNames, UINT,cNames, MEMBERID*,pMemId) \ + ICOM_METHOD7(HRESULT,Invoke, PVOID,pvInstance, MEMBERID,memid, WORD,wFlags, DISPPARAMS*,pDispParams, VARIANT*,pVarResult, EXCEPINFO*,pExcepInfo, UINT*,puArgErr) \ + ICOM_METHOD5(HRESULT,GetDocumentation, MEMBERID,memid, BSTR*,pBstrName, BSTR*,pBstrDocString, DWORD*,pdwHelpContext, BSTR*,pBstrHelpFile) \ + ICOM_METHOD5(HRESULT,GetDllEntry, MEMBERID,memid, INVOKEKIND,invKind, BSTR*,pBstrDllName, BSTR*,pBstrName, WORD*,pwOrdinal) \ + ICOM_METHOD2(HRESULT,GetRefTypeInfo, HREFTYPE,hRefType, ITypeInfo**,ppTInfo) \ + ICOM_METHOD3(HRESULT,AddressOfMember, MEMBERID,memid, INVOKEKIND,invKind, PVOID*,ppv) \ + ICOM_METHOD3(HRESULT,CreateInstance, IUnknown*,pUnkOuter, REFIID,riid, PVOID*,ppvObj) \ + ICOM_METHOD2(HRESULT,GetMops, MEMBERID,memid, BSTR*,pBstrMops) \ + ICOM_METHOD2(HRESULT,GetContainingTypeLib, ITypeLib**,ppTLib, UINT*,pIndex) \ + ICOM_METHOD1(HRESULT,ReleaseTypeAttr, TYPEATTR*,pTypeAttr) \ + ICOM_METHOD1(HRESULT,ReleaseFuncDesc, FUNCDESC*,pFuncDesc) \ + ICOM_METHOD1(HRESULT,ReleaseVarDesc, VARDESC*,pVarDesc) + +#define ITypeInfo_IMETHODS \ + IUnknown_IMETHODS \ + ITypeInfo_METHODS +ICOM_DEFINE(ITypeInfo,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ITypeInfo_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ITypeInfo_AddRef(p) ICOM_CALL (AddRef,p) +#define ITypeInfo_Release(p) ICOM_CALL (Release,p) +/*** ITypeInfo methods ***/ +#define ITypeInfo_GetTypeAttr(p,a) ICOM_CALL1(GetTypeAttr,p,a) +#define ITypeInfo_GetTypeComp(p,a) ICOM_CALL1(GetTypeComp,p,a) +#define ITypeInfo_GetFuncDesc(p,a,b) ICOM_CALL2(GetFuncDesc,p,a,b) +#define ITypeInfo_GetVarDesc(p,a,b) ICOM_CALL2(GetVarDesc,p,a,b) +#define ITypeInfo_GetNames(p,a,b,c,d) ICOM_CALL4(GetNames,p,a,b,c,d) +#define ITypeInfo_GetRefTypeOfImplType(p,a,b) ICOM_CALL2(GetRefTypeOfImplType,p,a,b) +#define ITypeInfo_GetImplTypeFlags(p,a,b) ICOM_CALL2(GetImplTypeFlags,p,a,b) +#define ITypeInfo_GetIDsOfNames(p,a,b,c) ICOM_CALL3(GetIDsOfNames,p,a,b,c) +#define ITypeInfo_Invoke(p,a,b,c,d,e,f,g) ICOM_CALL7(Invoke,p,a,b,c,d,e,f,g) +#define ITypeInfo_GetDocumentation(p,a,b,c,d,e) ICOM_CALL5(GetDocumentation,p,a,b,c,d,e) +#define ITypeInfo_GetDllEntry(p,a,b,c,d,e) ICOM_CALL5(GetDllEntry,p,a,b,c,d,e) +#define ITypeInfo_GetRefTypeInfo(p,a,b) ICOM_CALL2(GetRefTypeInfo,p,a,b) +#define ITypeInfo_AddressOfMember(p,a,b,c) ICOM_CALL3(AddressOfMember,p,a,b,c) +#define ITypeInfo_CreateInstance(p,a,b,c) ICOM_CALL3(CreateInstance,p,a,b,c) +#define ITypeInfo_GetMops(p,a,b) ICOM_CALL2(GetMops,p,a,b) +#define ITypeInfo_GetContainingTypeLib(p,a,b) ICOM_CALL2(GetContainingTypeLib,p,a,b) +#define ITypeInfo_ReleaseTypeAttr(p,a) ICOM_CALL1(ReleaseTypeAttr,p,a) +#define ITypeInfo_ReleaseFuncDesc(p,a) ICOM_CALL1(ReleaseFuncDesc,p,a) +#define ITypeInfo_ReleaseVarDesc(p,a) ICOM_CALL1(ReleaseVarDesc,p,a) + + +/***************************************************************************** + * ITypeInfo2 interface + */ +#define ICOM_INTERFACE ITypeInfo2 +#define ITypeInfo2_METHODS \ + ICOM_METHOD1(HRESULT, GetTypeKind, TYPEKIND*, pTypeKind) \ + ICOM_METHOD1(HRESULT, GetTypeFlags, UINT*, pTypeFlags) \ + ICOM_METHOD3(HRESULT, GetFuncIndexOfMemId, MEMBERID, memid, INVOKEKIND,\ + invKind, UINT*, pFuncIndex) \ + ICOM_METHOD2(HRESULT, GetVarIndexOfMemId, MEMBERID, memid, UINT*, \ + pVarIndex) \ + ICOM_METHOD2(HRESULT, GetCustData, REFGUID, guid, VARIANT*, pVarVal) \ + ICOM_METHOD3(HRESULT, GetFuncCustData, UINT, index, REFGUID, guid,\ + VARIANT*, pVarVal) \ + ICOM_METHOD4(HRESULT, GetParamCustData, UINT, indexFunc, UINT,\ + indexParam, REFGUID, guid, VARIANT*, pVarVal) \ + ICOM_METHOD3(HRESULT, GetVarCustData, UINT, index, REFGUID, guid,\ + VARIANT*, pVarVal) \ + ICOM_METHOD3(HRESULT, GetImplTypeCustData, UINT, index, REFGUID, guid,\ + VARIANT*, pVarVal) \ + ICOM_METHOD5(HRESULT, GetDocumentation2, MEMBERID, memid, LCID, lcid,\ + BSTR*, pbstrHelpString, DWORD*, pdwHelpStringContext,\ + BSTR*, pbstrHelpStringDll) \ + ICOM_METHOD1(HRESULT, GetAllCustData, CUSTDATA*, pCustData) \ + ICOM_METHOD2(HRESULT, GetAllFuncCustData, UINT, index, CUSTDATA*,\ + pCustData)\ + ICOM_METHOD3(HRESULT, GetAllParamCustData, UINT, indexFunc, UINT,\ + indexParam, CUSTDATA*, pCustData) \ + ICOM_METHOD2(HRESULT, GetAllVarCustData, UINT, index, CUSTDATA*,\ + pCustData) \ + ICOM_METHOD2(HRESULT, GetAllImplTypeCustData, UINT, index, CUSTDATA*,\ + pCustData) + +#define ITypeInfo2_IMETHODS \ + IUnknown_IMETHODS \ + ITypeInfo_METHODS \ + ITypeInfo2_METHODS +ICOM_DEFINE(ITypeInfo2,ITypeInfo) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ITypeInfo2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ITypeInfo2_AddRef(p) ICOM_CALL (AddRef,p) +#define ITypeInfo2_Release(p) ICOM_CALL (Release,p) +/*** ITypeInfo methods ***/ +#define ITypeInfo2_GetTypeAttr(p,a) ICOM_CALL1(GetTypeAttr,p,a) +#define ITypeInfo2_GetTypeComp(p,a) ICOM_CALL1(GetTypeComp,p,a) +#define ITypeInfo2_GetFuncDesc(p,a,b) ICOM_CALL2(GetFuncDesc,p,a,b) +#define ITypeInfo2_GetVarDesc(p,a,b) ICOM_CALL2(GetVarDesc,p,a,b) +#define ITypeInfo2_GetNames(p,a,b,c,d) ICOM_CALL4(GetNames,p,a,b,c,d) +#define ITypeInfo2_GetRefTypeOfImplType(p,a,b) ICOM_CALL2(GetRefTypeOfImplType,p,a,b) +#define ITypeInfo2_GetImplTypeFlags(p,a,b) ICOM_CALL2(GetImplTypeFlags,p,a,b) +#define ITypeInfo2_GetIDsOfNames(p,a,b,c) ICOM_CALL3(GetIDsOfNames,p,a,b,c) +#define ITypeInfo2_Invoke(p,a,b,c,d,e,f,g) ICOM_CALL7(Invoke,p,a,b,c,d,e,f,g) +#define ITypeInfo2_GetDocumentation(p,a,b,c,d,e) ICOM_CALL5(GetDocumentation,p,a,b,c,d,e) +#define ITypeInfo2_GetDllEntry(p,a,b,c,d,e) ICOM_CALL5(GetDllEntry,p,a,b,c,d,e) +#define ITypeInfo2_GetRefTypeInfo(p,a,b) ICOM_CALL2(GetRefTypeInfo,p,a,b) +#define ITypeInfo2_AddressOfMember(p,a,b,c) ICOM_CALL3(AddressOfMember,p,a,b,c) +#define ITypeInfo2_CreateInstance(p,a,b,c) ICOM_CALL3(CreateInstance,p,a,b,c) +#define ITypeInfo2_GetMops(p,a,b) ICOM_CALL2(GetMops,p,a,b) +#define ITypeInfo2_GetContainingTypeLib(p,a,b) ICOM_CALL2(GetContainingTypeLib,p,a,b) +#define ITypeInfo2_ReleaseTypeAttr(p,a) ICOM_CALL1(ReleaseTypeAttr,p,a) +#define ITypeInfo2_ReleaseFuncDesc(p,a) ICOM_CALL1(ReleaseFuncDesc,p,a) +#define ITypeInfo2_ReleaseVarDesc(p,a) ICOM_CALL1(ReleaseVarDesc,p,a) +/*** ITypeInfo2 methods ***/ +#define ITypeInfo2_GetTypeKind(p,a) ICOM_CALL1(GetTypeKind,p,a) +#define ITypeInfo2_GetTypeFlags(p,a) ICOM_CALL1(GetTypeFlags,p,a) +#define ITypeInfo2_GetFuncIndexOfMemId(p,a,b,c) ICOM_CALL3(GetFuncIndexOfMemId,p,a,b,c) +#define ITypeInfo2_GetVarIndexOfMemId(p,a,b) ICOM_CALL2(GetVarIndexOfMemId,p,a,b) +#define ITypeInfo2_GetCustData(p,a,b) ICOM_CALL2(GetCustData,p,a,b) +#define ITypeInfo2_GetFuncCustData(p,a,b,c) ICOM_CALL3(GetFuncCustData,p,a,b,c) +#define ITypeInfo2_GetParamCustData(p,a,b,c,d) ICOM_CALL4(GetParamCustData,p,a,b,c,d) +#define ITypeInfo2_GetVarCustData(p,a,b,c) ICOM_CALL3(GetVarCustData,p,a,b,c) +#define ITypeInfo2_GetImplTypeCustData(p,a,b,c) ICOM_CALL3(GetImplTypeCustData,p,a,b,c) +#define ITypeInfo2_GetDocumentation2(p,a,b,c,d,e) ICOM_CALL5(GetDocumentation2,p,a,b,c,d,e) +#define ITypeInfo2_GetAllCustData(p,a) ICOM_CALL1(GetAllCustData,p,a) +#define ITypeInfo2_GetAllFuncCustData(p,a,b) ICOM_CALL2(GetAllFuncCustData,p,a,b) +#define ITypeInfo2_GetAllParamCustData(p,a,b,c) ICOM_CALL3(GetAllParamCustData,p,a,b,c) +#define ITypeInfo2_GetAllVarCustData(p,a,b) ICOM_CALL2(GetAllVarCustData,p,a,b) +#define ITypeInfo2_GetAllImplTypeCustData(p,a,b) ICOM_CALL2(GetAllImplTypeCustData,p,a,b) + +/***************************************************************************** + * ITypeLib interface + */ +#define ICOM_INTERFACE ITypeLib +#define ITypeLib_METHODS \ + ICOM_METHOD (UINT,GetTypeInfoCount) \ + ICOM_METHOD2(HRESULT,GetTypeInfo, UINT,index, ITypeInfo**,ppTInfo) \ + ICOM_METHOD2(HRESULT,GetTypeInfoType, UINT,index, TYPEKIND*,pTKind) \ + ICOM_METHOD2(HRESULT,GetTypeInfoOfGuid, REFGUID,guid, ITypeInfo**,ppTinfo) \ + ICOM_METHOD1(HRESULT,GetLibAttr, TLIBATTR**,ppTLibAttr) \ + ICOM_METHOD1(HRESULT,GetTypeComp, ITypeComp**,ppTComp) \ + ICOM_METHOD5(HRESULT,GetDocumentation, INT,index, BSTR*,pBstrName, BSTR*,pBstrDocString, DWORD*,pdwHelpContext, BSTR*,pBstrHelpFile) \ + ICOM_METHOD3(HRESULT,IsName, LPOLESTR,szNameBuf, ULONG,lHashVal, BOOL*,bfName) \ + ICOM_METHOD5(HRESULT,FindName, LPOLESTR,szNameBuf, ULONG,lHashVal, ITypeInfo**,ppTInfo, MEMBERID*,rgMemId, USHORT*,pcFound) \ + ICOM_METHOD1(VOID,ReleaseTLibAttr, TLIBATTR*,pTLibAttr) +#define ITypeLib_IMETHODS \ + IUnknown_IMETHODS \ + ITypeLib_METHODS +ICOM_DEFINE(ITypeLib,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ITypeLib_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ITypeLib_AddRef(p) ICOM_CALL (AddRef,p) +#define ITypeLib_Release(p) ICOM_CALL (Release,p) +/*** ITypeLib methods ***/ +#define ITypeLib_GetTypeInfoCount(p) ICOM_CALL (GetTypeInfoCount,p) +#define ITypeLib_GetTypeInfo(p,a,b) ICOM_CALL2(GetTypeInfo,p,a,b) +#define ITypeLib_GetTypeInfoType(p,a,b) ICOM_CALL2(GetTypeInfoType,p,a,b) +#define ITypeLib_GetTypeInfoOfGuid(p,a,b) ICOM_CALL2(GetTypeInfoOfGuid,p,a,b) +#define ITypeLib_GetLibAttr(p,a) ICOM_CALL1(GetLibAttr,p,a) +#define ITypeLib_GetTypeComp(p,a) ICOM_CALL1(GetTypeComp,p,a) +#define ITypeLib_GetDocumentation(p,a,b,c,d,e) ICOM_CALL5(GetDocumentation,p,a,b,c,d,e) +#define ITypeLib_IsName(p,a,b,c) ICOM_CALL3(IsName,p,a,b,c) +#define ITypeLib_FindName(p,a,b,c,d,e) ICOM_CALL5(FindName,p,a,b,c,d,e) +#define ITypeLib_ReleaseTLibAttr(p,a) ICOM_CALL1(ReleaseTLibAttr,p,a) + + +/***************************************************************************** + * ITypeLib2 interface + */ +#define ICOM_INTERFACE ITypeLib2 +#define ITypeLib2_METHODS \ + ICOM_METHOD2(HRESULT, GetCustData, REFGUID, guid, VARIANT*, pVarVal) \ + ICOM_METHOD2(HRESULT, GetLibStatistics, ULONG *, pcUniqueNames, ULONG*,pcchUniqueNames) \ + ICOM_METHOD5(HRESULT, GetDocumentation2, INT, index, LCID, lcid,BSTR*, pbstrHelpString, DWORD*, pdwHelpStringContext, BSTR*, strHelpStringDll) \ + ICOM_METHOD1(HRESULT, GetAllCustData, CUSTDATA *, pCustData) +#define ITypeLib2_IMETHODS \ + IUnknown_IMETHODS \ + ITypeLib_IMETHODS \ + ITypeLib2_METHODS +ICOM_DEFINE(ITypeLib2,ITypeLib) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ITypeLib2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ITypeLib2_AddRef(p) ICOM_CALL (AddRef,p) +#define ITypeLib2_Release(p) ICOM_CALL (Release,p) +/*** ITypeLib methods ***/ +#define ITypeLib2_GetTypeInfoCount(p) ICOM_CALL (GetTypeInfoCount,p) +#define ITypeLib2_GetTypeInfo(p,a,b) ICOM_CALL2(GetTypeInfo,p,a,b) +#define ITypeLib2_GetTypeInfoType(p,a,b) ICOM_CALL2(GetTypeInfoType,p,a,b) +#define ITypeLib2_GetTypeInfoOfGuid(p,a,b) ICOM_CALL2(GetTypeInfoOfGuid,p,a,b) +#define ITypeLib2_GetLibAttr(p,a) ICOM_CALL1(GetLibAttr,p,a) +#define ITypeLib2_GetTypeComp(p,a) ICOM_CALL1(GetTypeComp,p,a) +#define ITypeLib2_GetDocumentation(p,a,b,c,d,e) ICOM_CALL5(GetDocumentation,p,a,b,c,d,e) +#define ITypeLib2_IsName(p,a,b,c) ICOM_CALL3(IsName,p,a,b,c) +#define ITypeLib2_FindName(p,a,b,c,d,e) ICOM_CALL5(FindName,p,a,b,c,d,e) +#define ITypeLib2_ReleaseTLibAttr(p,a) ICOM_CALL1(ReleaseTLibAttr,p,a) +/*** ITypeLib2 methods ***/ +#define ITypeLib2_GetCustData(p,a,b) ICOM_CALL2(GetCustData,p,a,b) +#define ITypeLib2_GetLibStatistics(p,a,b) ICOM_CALL2(GetLibStatistics,p,a,b) +#define ITypeLib2_GetDocumentation2(p,a,b,c,d,e,f) ICOM_CALL5(GetDocumentation2,p,a,b,c,d,e) +#define ITypeLib2_GetAllCustData(p,a) ICOM_CALL1(GetAllCustData,p,a) + +/***************************************************************************** + * ITypeComp interface + */ +#define ICOM_INTERFACE ITypeComp +#define ITypeComp_METHODS \ + ICOM_METHOD6(HRESULT,Bind, LPOLESTR,szName, ULONG,lHashVal, WORD,wFlags, ITypeInfo**,ppTInfo, DESCKIND*,pDescKind, BINDPTR*,pBindPtr) \ + ICOM_METHOD4(HRESULT,BindType, LPOLESTR,szName, ULONG,lHashVal, ITypeInfo**,ppTInfo, ITypeComp**,ppTComp) +#define ITypeComp_IMETHODS \ + IUnknown_IMETHODS \ + ITypeComp_METHODS +ICOM_DEFINE(ITypeComp,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ITypeComp_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ITypeComp_AddRef(p) ICOM_CALL (AddRef,p) +#define ITypeComp_Release(p) ICOM_CALL (Release,p) +/*** ITypeComp methods ***/ +#define ITypeComp_Bind(p,a,b,c,d,e,f) ICOM_CALL6(Bind,p,a,b,c,d,e,f) +#define ITypeComp_BindType(p,a,b,c,d) ICOM_CALL4(BindType,p,a,b,c,d) + +/***************************************************************************** + * IEnumVARIANT interface + */ +#define ICOM_INTERFACE IEnumVARIANT +#define IEnumVARIANT_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, VARIANT*,rgVar, ULONG*,pCeltFetched) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumVARIANT**,ppEnum) +#define IEnumVARIANT_IMETHODS \ + IUnknown_IMETHODS \ + IEnumVARIANT_METHODS +ICOM_DEFINE(IEnumVARIANT,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumVARIANT_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumVARIANT_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumVARIANT_Release(p) ICOM_CALL (Release,p) +/*** IEnumVARIANT methods ***/ +#define IEnumVARIANT_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumVARIANT_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumVARIANT_Reset(p) ICOM_CALL (Reset,p) +#define IEnumVARIANT_Clone(p,a) ICOM_CALL1(Clone,p,a) + +#endif /* __WINE_WINE_OBJ_OLEAUT_H */ + diff --git a/reactos/include/ole32/obj_olefont.h b/reactos/include/ole32/obj_olefont.h new file mode 100644 index 00000000000..c0edcf448a9 --- /dev/null +++ b/reactos/include/ole32/obj_olefont.h @@ -0,0 +1,119 @@ +/* + * Defines the COM interfaces and APIs related to OLE font support. + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_OLEFONT_H +#define __WINE_WINE_OBJ_OLEFONT_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID(IID_IFont, 0xBEF6E002, 0xA874, 0x101A, 0x8B, 0xBA, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB); +typedef struct IFont IFont,*LPFONT; + +DEFINE_GUID(IID_IFontDisp, 0xBEF6E003, 0xA874, 0x101A, 0x8B, 0xBA, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB); +typedef struct IFontDisp IFontDisp,*LPFONTDISP; + +typedef TEXTMETRICW TEXTMETRICOLE; + +/***************************************************************************** + * IFont interface + */ +#define ICOM_INTERFACE IFont +#define IFont_METHODS \ + ICOM_METHOD1(HRESULT, get_Name, BSTR*, pname) \ + ICOM_METHOD1(HRESULT, put_Name, BSTR, name) \ + ICOM_METHOD1(HRESULT, get_Size, CY*, psize) \ + ICOM_METHOD1(HRESULT, put_Size, CY, size) \ + ICOM_METHOD1(HRESULT, get_Bold, BOOL*, pbold) \ + ICOM_METHOD1(HRESULT, put_Bold, BOOL, bold) \ + ICOM_METHOD1(HRESULT, get_Italic, BOOL*, pitalic) \ + ICOM_METHOD1(HRESULT, put_Italic, BOOL, italic) \ + ICOM_METHOD1(HRESULT, get_Underline, BOOL*, punderline) \ + ICOM_METHOD1(HRESULT, put_Underline, BOOL, underline) \ + ICOM_METHOD1(HRESULT, get_Strikethrough, BOOL*, pstrikethrough) \ + ICOM_METHOD1(HRESULT, put_Strikethrough, BOOL, strikethrough) \ + ICOM_METHOD1(HRESULT, get_Weight, short*, pweight) \ + ICOM_METHOD1(HRESULT, put_Weight, short, weight) \ + ICOM_METHOD1(HRESULT, get_Charset, short*, pcharset) \ + ICOM_METHOD1(HRESULT, put_Charset, short, charset) \ + ICOM_METHOD1(HRESULT, get_hFont, HFONT*, phfont) \ + ICOM_METHOD1(HRESULT, Clone, IFont**, ppfont) \ + ICOM_METHOD1(HRESULT, IsEqual, IFont*, pFontOther) \ + ICOM_METHOD2(HRESULT, SetRatio, long, cyLogical, long, cyHimetric) \ + ICOM_METHOD1(HRESULT, QueryTextMetrics, TEXTMETRICOLE*, ptm) \ + ICOM_METHOD1(HRESULT, AddRefHfont, HFONT, hfont) \ + ICOM_METHOD1(HRESULT, ReleaseHfont, HFONT, hfont) \ + ICOM_METHOD1(HRESULT, SetHdc, HDC, hdc) +#define IFont_IMETHODS \ + IUnknown_IMEHTODS \ + IFont_METHODS +ICOM_DEFINE(IFont,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IFont_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IFont_AddRef(p) ICOM_CALL (AddRef,p) +#define IFont_Release(p) ICOM_CALL (Release,p) +/*** IFont methods ***/ +#define IFont_getName(p,a) ICOM_CALL1(get_Name,p,a) +#define IFont_putName(p,a) ICOM_CALL1(put_Name,p,a) +#define IFont_get_Size(p,a) ICOM_CALL1(get_Size,p,a) +#define IFont_put_Size(p,a) ICOM_CALL1(put_Size,p,a) +#define IFont_get_Bold(p,a) ICOM_CALL1(get_Bold,a) +#define IFont_put_Bold(p,a) ICOM_CALL1(put_Bold,a) +#define IFont_get_Italic(p,a) ICOM_CALL1(get_Italic,a) +#define IFont_put_Italic(p,a) ICOM_CALL1(put_Italic,a) +#define IFont_get_Underline(p,a) ICOM_CALL1(get_Underline,a) +#define IFont_put_Underline(p,a) ICOM_CALL1(put_Underline,a) +#define IFont_get_Strikethrough(p,a) ICOM_CALL1(get_Strikethrough,a) +#define IFont_put_Strikethrough(p,a) ICOM_CALL1(put_Strikethrough,a) +#define IFont_get_Weight(p,a) ICOM_CALL1(get_Weight,a) +#define IFont_put_Weight(p,a) ICOM_CALL1(put_Weight,a) +#define IFont_get_Charset(p,a) ICOM_CALL1(get_Charset,a) +#define IFont_put_Charset(p,a) ICOM_CALL1(put_Charset,a) +#define IFont_get_hFont(p,a) ICOM_CALL1(get_hFont,a) +#define IFont_put_hFont(p,a) ICOM_CALL1(put_hFont,a) +#define IFont_Clone(p,a) ICOM_CALL1(Clone,a) +#define IFont_IsEqual(p,a) ICOM_CALL1(IsEqual,a) +#define IFont_SetRatio(p,a,b) ICOM_CALL2(SetRatio,a,b) +#define IFont_QueryTextMetrics(p,a) ICOM_CALL1(QueryTextMetrics,a) +#define IFont_AddRefHfont(p,a) ICOM_CALL1(AddRefHfont,a) +#define IFont_ReleaseHfont(p,a) ICOM_CALL1(ReleaseHfont,a) +#define IFont_SetHdc(p,a) ICOM_CALL1(SetHdc,a) + +/***************************************************************************** + * IFont interface + */ +#define ICOM_INTERFACE IFontDisp +#define IFontDisp_METHODS +#define IFontDisp_IMETHODS \ + IUnknown_IMETHODS \ + IFontDisp_METHODS +ICOM_DEFINE(IFontDisp,IDispatch) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IFontDisp_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IFontDisp_AddRef(p) ICOM_CALL (AddRef,p) +#define IFontDisp_Release(p) ICOM_CALL (Release,p) +/*** IDispatch methods ***/ +#define IFontDisp_GetTypeInfoCount(p,a) ICOM_CALL1 (GetTypeInfoCount,p,a) +#define IFontDisp_GetTypeInfo(p,a,b,c) ICOM_CALL3 (GetTypeInfo,p,b,c) +#define IFontDisp_GetIDsOfNames(p,a,b,c,d,e) ICOM_CALL5 (GetIDsOfNames,p,a,b,c,d,e) +#define IFontDisp_Invoke(p,a,b,c,d,e,f,g,h) ICOM_CALL8 (Invoke,p,a,b,c,d,e,f,g,h) +/*** IFontDisp methods ***/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_OLEFONT_H */ + + diff --git a/reactos/include/ole32/obj_oleobj.h b/reactos/include/ole32/obj_oleobj.h new file mode 100644 index 00000000000..fa6df7e86db --- /dev/null +++ b/reactos/include/ole32/obj_oleobj.h @@ -0,0 +1,196 @@ +/* + * Defines IOleObject COM and other oleidl.h interfaces + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_OLEOBJ_H +#define __WINE_WINE_OBJ_OLEOBJ_H + +struct tagMSG; +struct tagLOGPALETTE; + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Declare the structures + */ +typedef struct tagOBJECTDESCRIPTOR +{ + ULONG cbSize; + CLSID clsid; + DWORD dwDrawAspect; + SIZEL sizel; + POINTL pointl; + DWORD dwStatus; + DWORD dwFullUserTypeName; + DWORD dwSrcOfCopy; +} OBJECTDESCRIPTOR, *LPOBJECTDESCRIPTOR; + +typedef enum tagOLEMISC +{ + OLEMISC_RECOMPOSEONRESIZE = 0x1, + OLEMISC_ONLYICONIC = 0x2, + OLEMISC_INSERTNOTREPLACE = 0x4, + OLEMISC_STATIC = 0x8, + OLEMISC_CANTLINKINSIDE = 0x10, + OLEMISC_CANLINKBYOLE1 = 0x20, + OLEMISC_ISLINKOBJECT = 0x40, + OLEMISC_INSIDEOUT = 0x80, + OLEMISC_ACTIVATEWHENVISIBLE = 0x100, + OLEMISC_RENDERINGISDEVICEINDEPENDENT = 0x200, + OLEMISC_INVISIBLEATRUNTIME = 0x400, + OLEMISC_ALWAYSRUN = 0x800, + OLEMISC_ACTSLIKEBUTTON = 0x1000, + OLEMISC_ACTSLIKELABEL = 0x2000, + OLEMISC_NOUIACTIVATE = 0x4000, + OLEMISC_ALIGNABLE = 0x8000, + OLEMISC_SIMPLEFRAME = 0x10000, + OLEMISC_SETCLIENTSITEFIRST = 0x20000, + OLEMISC_IMEMODE = 0x40000, + OLEMISC_IGNOREACTIVATEWHENVISIBLE = 0x80000, + OLEMISC_WANTSTOMENUMERGE = 0x100000, + OLEMISC_SUPPORTSMULTILEVELUNDO = 0x200000 +} OLEMISC; + +typedef enum tagOLEVERBATTRIB +{ + OLEVERBATTRIB_NEVERDIRTIES = 1, + OLEVERBATTRIB_ONCONTAINERMENU = 2 +} OLEVERBATTRIB; + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IOleObject, 0x00000112L, 0, 0); +typedef struct IOleObject IOleObject, *LPOLEOBJECT; + +DEFINE_OLEGUID(IID_IOleAdviseHolder, 0x00000111L, 0, 0); +typedef struct IOleAdviseHolder IOleAdviseHolder, *LPOLEADVISEHOLDER; + +DEFINE_OLEGUID(IID_IEnumOLEVERB, 0x00000104L, 0, 0); +typedef struct IEnumOLEVERB IEnumOLEVERB, *LPENUMOLEVERB; + +/***************************************************************************** + * IOleObject interface + */ +#define ICOM_INTERFACE IOleObject +#define IOleObject_METHODS \ + ICOM_METHOD1(HRESULT,SetClientSite, IOleClientSite*,pClientSite) \ + ICOM_METHOD1(HRESULT,GetClientSite, IOleClientSite**,ppClientSite) \ + ICOM_METHOD2(HRESULT,SetHostNames, LPCOLESTR,szContainerApp, LPCOLESTR,szContainerObj) \ + ICOM_METHOD1(HRESULT,Close, DWORD,dwSaveOption) \ + ICOM_METHOD2(HRESULT,SetMoniker, DWORD,dwWhichMoniker, IMoniker*,pmk) \ + ICOM_METHOD3(HRESULT,GetMoniker, DWORD,dwAssign, DWORD,dwWhichMoniker, IMoniker**,ppmk) \ + ICOM_METHOD3(HRESULT,InitFromData, IDataObject*,pDataObject, BOOL,fCreation, DWORD,dwReserved) \ + ICOM_METHOD2(HRESULT,GetClipboardData, DWORD,dwReserved, IDataObject**,ppDataObject) \ + ICOM_METHOD6(HRESULT,DoVerb, LONG,iVerb, struct tagMSG*,lpmsg, IOleClientSite*,pActiveSite, LONG,lindex, HWND,hwndParent, LPCRECT,lprcPosRect) \ + ICOM_METHOD1(HRESULT,EnumVerbs, IEnumOLEVERB**,ppEnumOleVerb) \ + ICOM_METHOD (HRESULT,Update) \ + ICOM_METHOD (HRESULT,IsUpToDate) \ + ICOM_METHOD1(HRESULT,GetUserClassID, CLSID*,pClsid) \ + ICOM_METHOD2(HRESULT,GetUserType, DWORD,dwFormOfType, LPOLESTR*,pszUserType) \ + ICOM_METHOD2(HRESULT,SetExtent, DWORD,dwDrawAspect, SIZEL*,psizel) \ + ICOM_METHOD2(HRESULT,GetExtent, DWORD,dwDrawAspect, SIZEL*,psizel) \ + ICOM_METHOD2(HRESULT,Advise, IAdviseSink*,pAdvSink, DWORD*,pdwConnection) \ + ICOM_METHOD1(HRESULT,Unadvise, DWORD,dwConnection) \ + ICOM_METHOD1(HRESULT,EnumAdvise, IEnumSTATDATA**,ppenumAdvise) \ + ICOM_METHOD2(HRESULT,GetMiscStatus, DWORD,dwAspect, DWORD*,pdwStatus) \ + ICOM_METHOD1(HRESULT,SetColorScheme, struct tagLOGPALETTE*,pLogpal) +#define IOleObject_IMETHODS \ + IUnknown_IMETHODS \ + IOleObject_METHODS +ICOM_DEFINE(IOleObject,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleObject_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleObject_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleObject_Release(p) ICOM_CALL (Release,p) +/*** IOleObject methods ***/ +#define IOleObject_SetClientSite(p,a) ICOM_CALL1(SetClientSite,p,a) +#define IOleObject_GetClientSite(p,a,b) ICOM_CALL1(GetClientSite,p,a) +#define IOleObject_SetHostNames(p,a,b) ICOM_CALL2(SetHostNames,p,a,b) +#define IOleObject_Close(p,a,b) ICOM_CALL1(Close,p,a) +#define IOleObject_SetMoniker(p,a,b) ICOM_CALL2(SetMoniker,p,a,b) +#define IOleObject_GetMoniker(p,a,b) ICOM_CALL3(GetMoniker,p,a,b,c) +#define IOleObject_InitFromData(p,a,b) ICOM_CALL3(InitFromData,p,a,b,c) +#define IOleObject_GetClipboardData(p,a,b) ICOM_CALL2(GetClipboardData,p,a,b) +#define IOleObject_DoVerb(p,a,b) ICOM_CALL6(DoVerb,p,a,b,c,d,e,f) +#define IOleObject_EnumVerbs(p,a,b) ICOM_CALL1(EnumVerbs,p,a) +#define IOleObject_Update(p,a,b) ICOM_CALL (Update,p) +#define IOleObject_IsUpToDate(p,a,b) ICOM_CALL (IsUpToDate,p) +#define IOleObject_GetUserClassID(p,a,b) ICOM_CALL1(GetUserClassID,p,a) +#define IOleObject_GetUserType(p,a,b) ICOM_CALL2(GetUserType,p,a,b) +#define IOleObject_SetExtent(p,a,b) ICOM_CALL2(SetExtent,p,a,b) +#define IOleObject_GetExtent(p,a,b) ICOM_CALL2(GetExtent,p,a,b) +#define IOleObject_Advise(p,a,b) ICOM_CALL2(Advise,p,a,b) +#define IOleObject_Unadvise(p,a,b) ICOM_CALL1(Unadvise,p,a) +#define IOleObject_EnumAdvise(p,a,b) ICOM_CALL1(EnumAdvise,p,a) +#define IOleObject_GetMiscStatus(p,a,b) ICOM_CALL2(GetMiscStatus,p,a,b) +#define IOleObject_SetColorScheme(p,a,b) ICOM_CALL1(SetColorScheme,p,a) + + +/***************************************************************************** + * IOleAdviseHolder interface + */ +#define ICOM_INTERFACE IOleAdviseHolder +#define IOleAdviseHolder_METHODS \ + ICOM_METHOD2(HRESULT,Advise, IAdviseSink*,pAdvise, DWORD*,pdwConnection) \ + ICOM_METHOD1(HRESULT,Unadvise, DWORD,dwConnection) \ + ICOM_METHOD1(HRESULT,EnumAdvise, IEnumSTATDATA**,ppenumAdvise) \ + ICOM_METHOD1(HRESULT,SendOnRename, IMoniker*,pmk) \ + ICOM_METHOD (HRESULT,SendOnSave) \ + ICOM_METHOD (HRESULT,SendOnClose) +#define IOleAdviseHolder_IMETHODS \ + IUnknown_IMETHODS \ + IOleAdviseHolder_METHODS +ICOM_DEFINE(IOleAdviseHolder,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleAdviseHolder_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleAdviseHolder_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleAdviseHolder_Release(p) ICOM_CALL (Release,p) +/*** IOleAdviseHolder methods ***/ +#define IOleAdviseHolder_Advise(p,a,b) ICOM_CALL2(Advise,p,a,b) +#define IOleAdviseHolder_Unadvise(p,a) ICOM_CALL1(Unadvise,p,a) +#define IOleAdviseHolder_EnumAdvise(p,a) ICOM_CALL1(EnumAdvise,p,a) +#define IOleAdviseHolder_SendOnRename(p,a) ICOM_CALL1(SendOnRename,p,a) +#define IOleAdviseHolder_SendOnSave(p) ICOM_CALL (SendOnSave,p) +#define IOleAdviseHolder_SendOnClose(p) ICOM_CALL (SendOnClose,p) + + +/***************************************************************************** + * IEnumOLEVERB interface + */ +#define ICOM_INTERFACE IEnumOLEVERB +#define IEnumOLEVERB_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, LPOLEVERB,rgelt, ULONG*,pceltFetched) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumOLEVERB**,ppenum) +#define IEnumOLEVERB_IMETHODS \ + IUnknown_IMETHODS \ + IEnumOLEVERB_METHODS +ICOM_DEFINE(IEnumOLEVERB,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumOLEVERB_QueryInterface(p,a,b) ICOM_ICALL2(IUnknown,QueryInterface,p,a,b) +#define IEnumOLEVERB_AddRef(p) ICOM_ICALL (IUnknown,AddRef,p) +#define IEnumOLEVERB_Release(p) ICOM_ICALL (IUnknown,Release,p) +/*** IEnumOLEVERB methods ***/ +#define IEnumOLEVERB_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumOLEVERB_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumOLEVERB_Reset(p,a) ICOM_CALL (Reset,p) +#define IEnumOLEVERB_Clone(p,a) ICOM_CALL1(Clone,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_OLEOBJ_H */ + diff --git a/reactos/include/ole32/obj_oleundo.h b/reactos/include/ole32/obj_oleundo.h new file mode 100644 index 00000000000..b52fbe2ef60 --- /dev/null +++ b/reactos/include/ole32/obj_oleundo.h @@ -0,0 +1,289 @@ +/* + * Defines the COM interfaces and APIs from ocidl.h which pertain to Undo/Redo + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_OLEUNDO_H +#define __WINE_WINE_OBJ_OLEUNDO_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID(IID_IQuickActivate, 0xcf51ed10, 0x62fe, 0x11cf, 0xbf, 0x86, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0x36); +typedef struct IQuickActivate IQuickActivate,*LPQUICKACTIVATE; + +DEFINE_GUID(IID_IPointerInactive, 0x55980ba0, 0x35aa, 0x11cf, 0xb6, 0x71, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8); +typedef struct IPointerInactive IPointerInactive,*LPPOINTERINACTIVE; + +DEFINE_GUID(IID_IAdviseSinkEx, 0x3af24290, 0x0c96, 0x11ce, 0xa0, 0xcf, 0x00, 0xaa, 0x00, 0x60, 0x0a, 0xb8); +typedef struct IAdviseSinkEx IAdviseSinkEx,*LPADVISESINKEX; + +DEFINE_GUID(IID_IOleUndoManager, 0xd001f200, 0xef97, 0x11ce, 0x9b, 0xc9, 0x00, 0xaa, 0x00, 0x60, 0x8e, 0x01); +typedef struct IOleUndoManager IOleUndoManager,*LPOLEUNDOMANAGER; + +DEFINE_GUID(IID_IOleUndoUnit, 0x894ad3b0, 0xef97, 0x11ce, 0x9b, 0xc9, 0x00, 0xaa, 0x00, 0x60, 0x8e, 0x01); +typedef struct IOleUndoUnit IOleUndoUnit,*LPOLEUNDOUNIT; + +DEFINE_GUID(IID_IOleParentUndoUnit, 0xa1faf330, 0xef97, 0x11ce, 0x9b, 0xc9, 0x00, 0xaa, 0x00, 0x60, 0x8e, 0x01); +typedef struct IOleParentUndoUnit IOleParentUndoUnit,*LPOLEPARENTUNDOUNIT; + +DEFINE_GUID(IID_IEnumOleUndoUnits, 0xb3e7c340, 0xef97, 0x11ce, 0x9b, 0xc9, 0x00, 0xaa, 0x00, 0x60, 0x8e, 0x01); +typedef struct IEnumOleUndoUnits IEnumOleUndoUnits,*LPENUMOLEUNDOUNITS; + +/***************************************************************************** + * Declare the structures + */ +typedef enum tagQACONTAINERFLAGS +{ + QACONTAINER_SHOWHATCHING = 0x1, + QACONTAINER_SHOWGRABHANDLES = 0x2, + QACONTAINER_USERMODE = 0x4, + QACONTAINER_DISPLAYASDEFAULT = 0x8, + QACONTAINER_UIDEAD = 0x10, + QACONTAINER_AUTOCLIP = 0x20, + QACONTAINER_MESSAGEREFLECT = 0x40, + QACONTAINER_SUPPORTSMNEMONICS = 0x80 +} QACONTAINERFLAGS; + +typedef DWORD OLE_COLOR; + +typedef struct tagQACONTROL +{ + ULONG cbSize; + DWORD dwMiscStatus; + DWORD dwViewStatus; + DWORD dwEventCookie; + DWORD dwPropNotifyCookie; + DWORD dwPointerActivationPolicy; +} QACONTROL; + +typedef struct tagQACONTAINER +{ + ULONG cbSize; + IOleClientSite *pClientSite; + IAdviseSinkEx *pAdviseSink; + IPropertyNotifySink *pPropertyNotifySink; + IUnknown *pUnkEventSink; + DWORD dwAmbientFlags; + OLE_COLOR colorFore; + OLE_COLOR colorBack; + IFont *pFont; + IOleUndoManager *pUndoMgr; + DWORD dwAppearance; + LONG lcid; + HPALETTE hpal; + struct IBindHost *pBindHost; +} QACONTAINER; + +/***************************************************************************** + * IQuickActivate interface + */ +#define ICOM_INTERFACE IQuickActivate +#define IQuickActivate_METHODS \ + ICOM_METHOD2(HRESULT,QuickActivate, QACONTAINER*,pQaContainer, QACONTROL*,pQaControl) \ + ICOM_METHOD1(HRESULT,SetContentExtent, LPSIZEL,pSizel) \ + ICOM_METHOD1(HRESULT,GetContentExtent, LPSIZEL,pSizel) +#define IQuickActivate_IMETHODS \ + IUnknown_IMETHODS \ + IQuickActivate_METHODS +ICOM_DEFINE(IQuickActivate,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IQuickActivate_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IQuickActivate_AddRef(p) ICOM_CALL (AddRef,p) +#define IQuickActivate_Release(p) ICOM_CALL (Release,p) +/*** IQuickActivate methods ***/ +#define IQuickActivate_QuickActivate(p,a,b) ICOM_CALL2(QuickActivate,p,a,b) +#define IQuickActivate_SetContentExtent(p,a) ICOM_CALL1(SetContentExtent,p,a) +#define IQuickActivate_GetContentExtent(p,a) ICOM_CALL1(GetContentExtent,p,a) + + +/***************************************************************************** + * IPointerInactive interface + */ +#define ICOM_INTERFACE IPointerInactive +#define IPointerInactive_METHODS \ + ICOM_METHOD1(HRESULT,GetActivationPolicy, DWORD*,pdwPolicy) \ + ICOM_METHOD4(HRESULT,OnInactiveMouseMove, LPCRECT,pRectBounds, LONG,x, LONG,y, DWORD,grfKeyState) \ + ICOM_METHOD5(HRESULT,OnInactiveSetCursor, LPCRECT,pRectBounds, LONG,x, LONG,y, DWORD,dwMouseMsg, BOOL,fSetAlways) +#define IPointerInactive_IMETHODS \ + IUnknown_IMETHODS \ + IPointerInactive_METHODS +ICOM_DEFINE(IPointerInactive,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPointerInactive_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPointerInactive_AddRef(p) ICOM_CALL (AddRef,p) +#define IPointerInactive_Release(p) ICOM_CALL (Release,p) +/*** IPointerInactive methods ***/ +#define IPointerInactive_GetActivationPolicy(p,a) ICOM_CALL1(GetActivationPolicy,p,a) +#define IPointerInactive_OnInactiveMoveMouse(p,a,b,c,d) ICOM_CALL4(OnInactiveMoveMouse,p,a,b,c,d) +#define IPointerInactive_OnInactiveSetCursor(p,a,b,c,d,e) ICOM_CALL5(OnInactiveSetCursor,p,a,b,d,e) + + +/***************************************************************************** + * IAdviseSinkEx interface + */ +#define ICOM_INTERFACE IAdviseSinkEx +#define IAdviseSinkEx_METHODS \ + ICOM_METHOD1(HRESULT,OnViewStatusChange, DWORD,dwViewStatus) +#define IAdviseSinkEx_IMETHODS \ + IAdviseSink_IMETHODS \ + IAdviseSinkEx_METHODS +ICOM_DEFINE(IAdviseSinkEx,IAdviseSink) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IAdviseSinkEx_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IAdviseSinkEx_AddRef(p) ICOM_CALL (AddRef,p) +#define IAdviseSinkEx_Release(p) ICOM_CALL (Release,p) +/*** IAdviseSink methods ***/ +#define IAdviseSinkEx_OnDataChange(p,a,b) ICOM_CALL2(OnDataChange,p,a,b) +#define IAdviseSinkEx_OnViewChange(p,a,b) ICOM_CALL2(OnViewChange,p,a,b) +#define IAdviseSinkEx_OnRename(p,a) ICOM_CALL1(OnRename,p,a) +#define IAdviseSinkEx_OnSave(p) ICOM_CALL (OnSave,p) +#define IAdviseSinkEx_OnClose(p) ICOM_CALL (OnClose,p) +/*** IAdviseSinkEx methods ***/ +#define IAdviseSinkEx_OnViewStatusChange(p,a) ICOM_CALL1(OnViewStatusChange,p,a) + + +/***************************************************************************** + * IOleUndoManager interface + */ +#define ICOM_INTERFACE IOleUndoManager +#define IOleUndoManager_METHODS \ + ICOM_METHOD1(HRESULT,Open, IOleParentUndoUnit*,pPUU) \ + ICOM_METHOD2(HRESULT,Close, IOleParentUndoUnit*,pPUU, BOOL,fCommit) \ + ICOM_METHOD1(HRESULT,Add, IOleUndoUnit*,pUU) \ + ICOM_METHOD1(HRESULT,GetOpenParentState, DWORD*,pdwState) \ + ICOM_METHOD1(HRESULT,DiscardFrom, IOleUndoUnit*,pUU) \ + ICOM_METHOD1(HRESULT,UndoTo, IOleUndoUnit*,pUU) \ + ICOM_METHOD1(HRESULT,RedoTo, IOleUndoUnit*,pUU) \ + ICOM_METHOD1(HRESULT,EnumUndoable, IEnumOleUndoUnits**,ppEnum) \ + ICOM_METHOD1(HRESULT,EnumRedoable, IEnumOleUndoUnits**,ppEnum) \ + ICOM_METHOD1(HRESULT,GetLastUndoDescription, BSTR*,pBstr) \ + ICOM_METHOD1(HRESULT,GetLastRedoDescription, BSTR*,pBstr) \ + ICOM_METHOD1(HRESULT,Enable, BOOL,fEnable) +#define IOleUndoManager_IMETHODS \ + IUnknown_IMETHODS \ + IOleUndoManager_METHODS +ICOM_DEFINE(IOleUndoManager,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleUndoManager_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleUndoManager_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleUndoManager_Release(p) ICOM_CALL (Release,p) +/*** IOleUndoManager methods ***/ +#define IOleUndoManager_Open(p,a) ICOM_CALL1(Open,p,a) +#define IOleUndoManager_Close(p,a,b) ICOM_CALL2(Close,p,a,b) +#define IOleUndoManager_Add(p,a) ICOM_CALL1(Add,p,a) +#define IOleUndoManager_GetOpenParentState(p,a) ICOM_CALL1(GetOpenParentState,p,a) +#define IOleUndoManager_DiscardFrom(p,a) ICOM_CALL1(DiscardFrom,p,a) +#define IOleUndoManager_UndoTo(p,a) ICOM_CALL1(UndoTo,p,a) +#define IOleUndoManager_RedoTo(p,a) ICOM_CALL1(RedoTo,p,a) +#define IOleUndoManager_EnumUndoable(p,a) ICOM_CALL1(EnumUndoable,p,a) +#define IOleUndoManager_EnumRedoable(p,a) ICOM_CALL1(EnumRedoable,p,a) +#define IOleUndoManager_GetLastUndoDescription(p,a) ICOM_CALL1(GetLastUndoDescription,p,a) +#define IOleUndoManager_GetLastRedoDescription(p,a) ICOM_CALL1(GetLastRedoDescription,p,a) +#define IOleUndoManager_Enable(p,a) ICOM_CALL1(Enable,p,a) + + +/***************************************************************************** + * IOleUndoUnit interface + */ +#define ICOM_INTERFACE IOleUndoUnit +#define IOleUndoUnit_METHODS \ + ICOM_METHOD1(HRESULT,Do, IOleUndoManager*,pUndoManager) \ + ICOM_METHOD1(HRESULT,GetDescription, BSTR*,pBstr) \ + ICOM_METHOD2(HRESULT,GetUnitType, CLSID*,pClsid, LONG*,plID) \ + ICOM_METHOD (HRESULT,OnNextAdd) +#define IOleUndoUnit_IMETHODS \ + IUnknown_IMETHODS \ + IOleUndoUnit_METHODS +ICOM_DEFINE(IOleUndoUnit,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleUndoUnit_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleUndoUnit_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleUndoUnit_Release(p) ICOM_CALL (Release,p) +/*** IOleUndoUnit methods ***/ +#define IOleUndoUnit_Do(p,a) ICOM_CALL1(Do,p,a) +#define IOleUndoUnit_GetDescription(p,a) ICOM_CALL1(GetDescription,p,a) +#define IOleUndoUnit_GetUnitType(p,a,b) ICOM_CALL2(GetUnitType,p,a,b) +#define IOleUndoUnit_OnNextAdd(p) ICOM_CALL (OnNextAdd,p) + + + +/***************************************************************************** + * IOleUndoUnit interface + */ +#define ICOM_INTERFACE IOleParentUndoUnit +#define IOleParentUndoUnit_METHODS \ + ICOM_METHOD1(HRESULT,Open, IOleParentUndoUnit*,pPUU) \ + ICOM_METHOD2(HRESULT,Close, IOleParentUndoUnit*,pPUU, BOOL,fCommit) \ + ICOM_METHOD1(HRESULT,Add, IOleUndoUnit*,pUU) \ + ICOM_METHOD1(HRESULT,FindUnit, IOleUndoUnit*,pUU) \ + ICOM_METHOD1(HRESULT,GetParentState, DWORD*,pdwState) +#define IOleParentUndoUnit_IMETHODS \ + IOleUndoUnit_IMETHODS \ + IOleParentUndoUnit_METHODS +ICOM_DEFINE(IOleParentUndoUnit,IOleUndoUnit) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IOleParentUndoUnit_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IOleParentUndoUnit_AddRef(p) ICOM_CALL (AddRef,p) +#define IOleParentUndoUnit_Release(p) ICOM_CALL (Release,p) +/*** IOleUndoUnit methods ***/ +#define IOleParentUndoUnit_Do(p,a) ICOM_CALL1(Do,p,a) +#define IOleParentUndoUnit_GetDescription(p,a) ICOM_CALL1(GetDescription,p,a) +#define IOleParentUndoUnit_GetUnitType(p,a,b) ICOM_CALL2(GetUnitType,p,a,b) +#define IOleParentUndoUnit_OnNextAdd(p) ICOM_CALL (OnNextAdd,p) +/*** IOleParentUndoUnit methods ***/ +#define IOleParentUndoUnit_Open(p,a) ICOM_CALL1(Open,p,a) +#define IOleParentUndoUnit_Close(p,a,b) ICOM_CALL2(Close,p,a,b) +#define IOleParentUndoUnit_Add(p,a) ICOM_CALL1(Add,p,a) +#define IOleParentUndoUnit_FindUnit(p,a) ICOM_CALL1(FindUnit,p,a) +#define IOleParentUndoUnit_GetParentState(p,a,b) ICOM_CALL1(GetParentState,p,a) + + +/***************************************************************************** + * IEnumOleUndoUnits interface + */ +#define ICOM_INTERFACE IEnumOleUndoUnits +#define IEnumOleUndoUnits_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,cElt, IOleUndoUnit**,rgElt, ULONG*,pcEltFetched) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,cElt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumOleUndoUnits**,ppEnum) +#define IEnumOleUndoUnits_IMETHODS \ + IUnknown_IMETHODS \ + IEnumOleUndoUnits_METHODS +ICOM_DEFINE(IEnumOleUndoUnits,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumOleUndoUnits_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumOleUndoUnits_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumOleUndoUnits_Release(p) ICOM_CALL (Release,p) +/*** IEnumOleUndoUnits methods ***/ +#define IEnumOleUndoUnits_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumOleUndoUnits_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumOleUndoUnits_Reset(p,a) ICOM_CALL (Reset,p,a) +#define IEnumOleUndoUnits_Clone(p,a) ICOM_CALL1(Clone,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_OLEUNDO_H */ + diff --git a/reactos/include/ole32/obj_oleview.h b/reactos/include/ole32/obj_oleview.h new file mode 100644 index 00000000000..b79deec46e9 --- /dev/null +++ b/reactos/include/ole32/obj_oleview.h @@ -0,0 +1,94 @@ +/* + * Defines the COM interfaces and APIs related to ViewObject + * + */ + +#ifndef __WINE_WINE_OBJ_OLEVIEW_H +#define __WINE_WINE_OBJ_OLEVIEW_H + +struct tagLOGPALETTE; + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Declare the structures + */ + + +/***************************************************************************** + * Predeclare the interfaces + */ + +DEFINE_OLEGUID(IID_IViewObject, 0x0000010dL, 0, 0); +typedef struct IViewObject IViewObject, *LPVIEWOBJECT; + +DEFINE_OLEGUID(IID_IViewObject2, 0x00000127L, 0, 0); +typedef struct IViewObject2 IViewObject2, *LPVIEWOBJECT2; + +/***************************************************************************** + * IViewObject interface + */ +typedef BOOL CALLBACK (*IVO_ContCallback)(DWORD); + +#define ICOM_INTERFACE IViewObject +#define IViewObject_METHODS \ + ICOM_METHOD10(HRESULT,Draw, DWORD,dwDrawAspect, LONG,lindex, void*,pvAspect, DVTARGETDEVICE*,ptd, HDC,hdcTargetDev, HDC,hdcDraw, LPCRECTL,lprcBounds, LPCRECTL,lprcWBounds, IVO_ContCallback, pfnContinue, DWORD,dwContinue) \ + ICOM_METHOD6(HRESULT,GetColorSet, DWORD,dwDrawAspect, LONG,lindex, void*,pvAspect, DVTARGETDEVICE*,ptd, HDC,hicTargetDevice, struct tagLOGPALETTE**,ppColorSet) \ + ICOM_METHOD4(HRESULT,Freeze, DWORD,dwDrawAspect, LONG,lindex, void*,pvAspect, DWORD*,pdwFreeze) \ + ICOM_METHOD1(HRESULT,Unfreeze, DWORD,dwFreeze) \ + ICOM_METHOD3(HRESULT,SetAdvise, DWORD,aspects, DWORD,advf, IAdviseSink*,pAdvSink) \ + ICOM_METHOD3(HRESULT,GetAdvise, DWORD*,pAspects, DWORD*,pAdvf, IAdviseSink**,ppAdvSink) +#define IViewObject_IMETHODS \ + IUnknown_IMETHODS \ + IViewObject_METHODS +ICOM_DEFINE(IViewObject,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IViewObject_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IViewObject_AddRef(p) ICOM_CALL (AddRef,p) +#define IViewObject_Release(p) ICOM_CALL (Release,p) +/*** IViewObject methods ***/ +#define IViewObject_Draw(p,a,b,c,d,e,f,g,h,i,j) ICOM_CALL10(Draw,p,a,b,c,d,e,f,g,h,i,j) +#define IViewObject_GetColorSet(p,a,b,c,d,e,f) ICOM_CALL6(GetColorSet,p,a,b,c,d,e,f) +#define IViewObject_Freeze(p,a,b,c,d) ICOM_CALL4(Freeze,p,a,b,c,d) +#define IViewObject_Unfreeze(p,a) ICOM_CALL1(Unfreeze,p,a) +#define IViewObject_SetAdvise(p,a,b,c) ICOM_CALL3(SetAdvise,p,a,b,c) +#define IViewObject_GetAdvise(p,a,b,c) ICOM_CALL3(GetAdvise,p,a,b,c) + + + +/***************************************************************************** + * IViewObject2 interface + */ +#define ICOM_INTERFACE IViewObject2 +#define IViewObject2_METHODS \ + ICOM_METHOD4(HRESULT,GetExtent, DWORD,dwDrawAspect, LONG,lindex, DVTARGETDEVICE*,ptd, LPSIZEL,lpsizel) +#define IViewObject2_IMETHODS \ + IViewObject_IMETHODS \ + IViewObject2_METHODS +ICOM_DEFINE(IViewObject2,IViewObject) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IViewObject2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IViewObject2_AddRef(p) ICOM_CALL (AddRef,p) +#define IViewObject2_Release(p) ICOM_CALL (Release,p) +/*** IViewObject methods ***/ +#define IViewObject2_Draw(p,a,b,c,d,e,f,g,h,i,j) ICOM_CALL10(Draw,p,a,b,c,d,e,f,g,h,i,j) +#define IViewObject2_GetColorSet(p,a,b,c,d,e,f) ICOM_CALL6(GetColorSet,p,a,b,c,d,e,f) +#define IViewObject2_Freeze(p,a,b,c,d) ICOM_CALL4(Freeze,p,a,b,c,d) +#define IViewObject2_Unfreeze(p,a) ICOM_CALL1(Unfreeze,p,a) +#define IViewObject2_SetAdvise(p,a,b,c) ICOM_CALL3(SetAdvise,p,a,b,c) +#define IViewObject2_GetAdvise(p,a,b,c) ICOM_CALL3(GetAdvise,p,a,b,c) +/*** IViewObject2 methods ***/ +#define IViewObject2_GetExtent(p,a,b,c,d) ICOM_CALL4(GetExtent,p,a,b,c,d) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_OLEVIEW_H */ + diff --git a/reactos/include/ole32/obj_picture.h b/reactos/include/ole32/obj_picture.h new file mode 100644 index 00000000000..2e2d55c4a3e --- /dev/null +++ b/reactos/include/ole32/obj_picture.h @@ -0,0 +1,108 @@ +/* + * Defines the COM interfaces and APIs related to OLE picture support. + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_PICTURE_H +#define __WINE_WINE_OBJ_PICTURE_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the structures + */ +typedef UINT OLE_HANDLE; +typedef LONG OLE_XPOS_HIMETRIC; +typedef LONG OLE_YPOS_HIMETRIC; +typedef LONG OLE_XSIZE_HIMETRIC; +typedef LONG OLE_YSIZE_HIMETRIC; + + + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID(IID_IPicture, 0x7bf80980, 0xbf32, 0x101a, 0x8b, 0xbb, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB); +typedef struct IPicture IPicture, *LPPICTURE; + +DEFINE_GUID(IID_IPictureDisp, 0x7bf80981, 0xbf32, 0x101a, 0x8b, 0xbb, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB); +typedef struct IPictureDisp IPictureDisp, *LPPICTUREDISP; + +/***************************************************************************** + * IPicture interface + */ +#define ICOM_INTERFACE IPicture +#define IPicture_METHODS \ + ICOM_METHOD1(HRESULT,get_Handle, OLE_HANDLE*,pHandle) \ + ICOM_METHOD1(HRESULT,get_hPal, OLE_HANDLE*,phPal) \ + ICOM_METHOD1(HRESULT,get_Type, SHORT*,pType) \ + ICOM_METHOD1(HRESULT,get_Width, OLE_XSIZE_HIMETRIC*,pWidth) \ + ICOM_METHOD1(HRESULT,get_Height, OLE_YSIZE_HIMETRIC*,pHeight) \ + ICOM_METHOD10(HRESULT,Render, HDC,hdc, LONG,x, LONG,y, LONG,cx, LONG,cy, OLE_XPOS_HIMETRIC,xSrc, OLE_YPOS_HIMETRIC,ySrc, OLE_XSIZE_HIMETRIC,cxSrc, OLE_YSIZE_HIMETRIC,cySrc, LPCRECT,pRcWBounds) \ + ICOM_METHOD1(HRESULT,set_hPal, OLE_HANDLE,hPal) \ + ICOM_METHOD1(HRESULT,get_CurDC, HDC*,phDC) \ + ICOM_METHOD3(HRESULT,SelectPicture, HDC,hDCIn, HDC*,phDCOut, OLE_HANDLE*,phBmpOut) \ + ICOM_METHOD1(HRESULT,get_KeepOriginalFormat, BOOL*,pKeep) \ + ICOM_METHOD1(HRESULT,put_KeepOriginalFormat, BOOL,Keep) \ + ICOM_METHOD (HRESULT,PictureChanged) \ + ICOM_METHOD3(HRESULT,SaveAsFile, LPSTREAM,pStream, BOOL,fSaveMemCopy, LONG*,pCbSize) \ + ICOM_METHOD1(HRESULT,get_Attributes, DWORD*,pDwAttr) +#define IPicture_IMETHODS \ + IUnknown_IMETHODS \ + IPicture_METHODS +ICOM_DEFINE(IPicture,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPicture_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPicture_AddRef(p) ICOM_CALL (AddRef,p) +#define IPicture_Release(p) ICOM_CALL (Release,p) +/*** IPicture methods ***/ +#define IPicture_get_Handle(p,a) ICOM_CALL1(get_Handle,p,a) +#define IPicture_get_hPal(p,a) ICOM_CALL1(get_hPal,p,a) +#define IPicture_get_Type(p,a) ICOM_CALL1(get_Type,p,a) +#define IPicture_get_Width(p,a) ICOM_CALL1(get_Width,p,a) +#define IPicture_get_Height(p,a) ICOM_CALL1(get_Height,p,a) +#define IPicture_Render(p,a,b,c,d,e,f,g,h,i,j) ICOM_CALL10(Render,p,a,b,c,d,e,f,g,h,i,j) +#define IPicture_set_hPal(p,a) ICOM_CALL1(set_hPal,p,a) +#define IPicture_get_CurDC(p,a) ICOM_CALL1(get_CurDC,p,a) +#define IPicture_SelectPicture(p,a,b,c) ICOM_CALL3(SelectPicture,p,a,b,c) +#define IPicture_get_KeepOriginalFormat(p,a) ICOM_CALL1(get_KeepOriginalFormat,p,a) +#define IPicture_put_KeepOriginalFormat(p,a) ICOM_CALL1(put_KeepOriginalFormat,p,a) +#define IPicture_PictureChanged(p) ICOM_CALL (PictureChanged,p) +#define IPicture_SaveAsFile(p,a,b,c) ICOM_CALL3(SaveAsFile,p,a,b,c) +#define IPicture_get_Attributes(p,a) ICOM_CALL1(get_Attributes,p,a) + + +/***************************************************************************** + * IPictureDisp interface + */ +#define ICOM_INTERFACE IPictureDisp +#define IPictureDisp_METHODS +#define IPictureDisp_IMETHODS \ + IDispatch_IMETHODS \ + IPictureDisp_METHODS +ICOM_DEFINE(IPictureDisp,IDispatch) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPictureDisp_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPictureDisp_AddRef(p) ICOM_CALL (AddRef,p) +#define IPictureDisp_Release(p) ICOM_CALL (Release,p) +/*** IDispatch methods ***/ +#define IPictureDisp_GetTypeInfoCount(p,a) ICOM_CALL1 (GetTypeInfoCount,p,a) +#define IPictureDisp_GetTypeInfo(p,a,b,c) ICOM_CALL3 (GetTypeInfo,p,b,c) +#define IPictureDisp_GetIDsOfNames(p,a,b,c,d,e) ICOM_CALL5 (GetIDsOfNames,p,a,b,c,d,e) +#define IPictureDisp_Invoke(p,a,b,c,d,e,f,g,h) ICOM_CALL8 (Invoke,p,a,b,c,d,e,f,g,h) +/*** IPictureDisp methods ***/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_PICTURE_H */ + + diff --git a/reactos/include/ole32/obj_property.h b/reactos/include/ole32/obj_property.h new file mode 100644 index 00000000000..8ab92ab98d2 --- /dev/null +++ b/reactos/include/ole32/obj_property.h @@ -0,0 +1,413 @@ +/* + * Defines the COM interfaces and APIs from ocidl.h related to property + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_PROPERTY_H +#define __WINE_WINE_OBJ_PROPERTY_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Declare the structures + */ +typedef struct tagPROPPAGEINFO +{ + ULONG cb; + LPOLESTR pszTitle; + SIZE size; + LPOLESTR pszDocString; + LPOLESTR pszHelpFile; + DWORD dwHelpContext; +} PROPPAGEINFO, *LPPROPPAGEINFO; + +typedef enum tagPROPPAGESTATUS +{ + PROPPAGESTATUS_DIRTY = 0x1, + PROPPAGESTATUS_VALIDATE = 0x2, + PROPPAGESTATUS_CLEAN = 0x4 +} PROPPAGESTATUS; + +typedef struct tagCAUUID +{ + ULONG cElems; + GUID* pElems; +} CAUUID, *LPCAUUID; + +typedef struct tagCALPOLESTR +{ + ULONG cElems; + LPOLESTR *pElems; +} CALPOLESTR, *LPCALPOLESTR; + +typedef struct tagCADWORD +{ + ULONG cElems; + DWORD *pElems; +} CADWORD, *LPCADWORD; + + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID(IID_IPropertyPage, 0xb196b28dL, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IPropertyPage IPropertyPage, *LPPROPERTYPAGE; + +DEFINE_GUID(IID_IPropertyPage2, 0x01e44665L, 0x24ac, 0x101b, 0x84, 0xed, 0x08, 0x00, 0x2b, 0x2e, 0xc7, 0x13); +typedef struct IPropertyPage2 IPropertyPage2, *LPPROPERTYPAGE2; + +DEFINE_GUID(IID_IPropertyPageSite, 0xb196b28cL, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IPropertyPageSite IPropertyPageSite, *LPPROPERTYPAGESITE; + +DEFINE_GUID(IID_IPropertyNotifySink, 0x9bfbbc02L, 0xeff1, 0x101a, 0x84, 0xed, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IPropertyNotifySink IPropertyNotifySink, *LPPROPERTYNOTIFYSINK; + +DEFINE_GUID(IID_ISimpleFrameSite, 0x742b0e01L, 0x14e6, 0x101b, 0x91, 0x4e, 0x00, 0xaa, 0x00, 0x30, 0x0c, 0xab); +typedef struct ISimpleFrameSite ISimpleFrameSite, *LPSIMPLEFRAMESITE; + +DEFINE_GUID(IID_IPersistStreamInit, 0x7fd52380L, 0x4e07, 0x101b, 0xae, 0x2d, 0x08, 0x00, 0x2b, 0x2e, 0xc7, 0x13); +typedef struct IPersistStreamInit IPersistStreamInit,*LPPERSISTSTREAMINIT; + +DEFINE_GUID(IID_IPersistMemory, 0xbd1ae5e0L, 0xa6ae, 0x11ce, 0xbd, 0x37, 0x50, 0x42, 0x00, 0xc1, 0x00, 0x00); +typedef struct IPersistMemory IPersistMemory,*LPPERSISTMEMORY; + +DEFINE_GUID(IID_IPersistPropertyBag, 0x37d84f60, 0x42cb, 0x11ce, 0x81, 0x35, 0x00, 0xaa, 0x00, 0x4b, 0xb8, 0x51); +typedef struct IPersistPropertyBag IPersistPropertyBag,*LPPERSISTPROPERTYBAG; + +DEFINE_GUID(IID_IErrorLog, 0x3127ca40L, 0x446e, 0x11ce, 0x81, 0x35, 0x00, 0xaa, 0x00, 0x4b, 0xb8, 0x51); +typedef struct IErrorLog IErrorLog,*LPERRORLOG; + +DEFINE_GUID(IID_IPropertyBag, 0x55272a00L, 0x42cb, 0x11ce, 0x81, 0x35, 0x00, 0xaa, 0x00, 0x4b, 0xb8, 0x51); +typedef struct IPropertyBag IPropertyBag,*LPPROPERTYBAG; + +DEFINE_GUID(IID_ISpecifyPropertyPages, 0xb196b28b, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct ISpecifyPropertyPages ISpecifyPropertyPages,*LPSPECIFYPROPERTYPAGES; + +DEFINE_GUID(IID_IPerPropertyBrowsing, 0xb196b28b, 0xbab4, 0x101a, 0xb6, 0x9c, 0x00, 0xaa, 0x00, 0x34, 0x1d, 0x07); +typedef struct IPerPropertyBrowsing IPerPropertyBrowsing,*LPPERPROPERTYBROWSING; + + +/***************************************************************************** + * IPropertPage interface + */ +#define ICOM_INTERFACE IPropertyPage +#define IPropertyPage_METHODS \ + ICOM_METHOD1(HRESULT,SetPageSite, IPropertyPageSite*,pPageSite) \ + ICOM_METHOD3(HRESULT,Activate, HWND,hWndParent, LPCRECT,pRect, BOOL,bModal) \ + ICOM_METHOD (HRESULT,Deactivate) \ + ICOM_METHOD1(HRESULT,GetPageInfo, PROPPAGEINFO*,pPageInfo) \ + ICOM_METHOD2(HRESULT,SetObjects, ULONG,cObjects, IUnknown**,ppUnk) \ + ICOM_METHOD1(HRESULT,Show, UINT,nCmdShow) \ + ICOM_METHOD1(HRESULT,Move, LPCRECT,pRect) \ + ICOM_METHOD (HRESULT,IsPageDirty) \ + ICOM_METHOD (HRESULT,Apply) \ + ICOM_METHOD1(HRESULT,Help, LPCOLESTR,pszHelpDir) \ + ICOM_METHOD1(HRESULT,TranslateAccelerator, MSG*,pMsg) +#define IPropertyPage_IMETHODS \ + IUnknown_IMETHODS \ + IPropertyPage_METHODS +ICOM_DEFINE(IPropertyPage,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPropertyPage_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPropertyPage_AddRef(p) ICOM_CALL (AddRef,p) +#define IPropertyPage_Release(p) ICOM_CALL (Release,p) +/*** IPropertyPage methods ***/ +#define IPropertyPage_SetPageSite(p,a) ICOM_CALL1(SetPageSite,p,a) +#define IPropertyPage_Activate(p,a,b,c) ICOM_CALL3(Activate,p,a,b,c) +#define IPropertyPage_Deactivate(p) ICOM_CALL (Deactivate,p) +#define IPropertyPage_GetPageInfo(p,a) ICOM_CALL1(GetPageInfo,p,a) +#define IPropertyPage_SetObjects(p,a,b) ICOM_CALL2(SetObjects,p,a,b) +#define IPropertyPage_Show(p,a) ICOM_CALL1(Show,p,a) +#define IPropertyPage_Move(p,a) ICOM_CALL1(Move,p,a) +#define IPropertyPage_IsPageDirty(p) ICOM_CALL (IsPageDirty,p) +#define IPropertyPage_Apply(p) ICOM_CALL (Apply,p) +#define IPropertyPage_Help(p,a) ICOM_CALL1(Help,p,a) +#define IPropertyPage_TranslateAccelerator(p,a) ICOM_CALL1(TranslateAccelerator,p,a) + + +/***************************************************************************** + * IPropertPage2 interface + */ +#define ICOM_INTERFACE IPropertyPage2 +#define IPropertyPage2_METHODS \ + ICOM_METHOD1(HRESULT,EditProperty, DISPID,dispID) +#define IPropertyPage2_IMETHODS \ + IPropertyPage_IMETHODS \ + IPropertyPage2_METHODS +ICOM_DEFINE(IPropertyPage2,IPropertyPage) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPropertyPage2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPropertyPage2_AddRef(p) ICOM_CALL (AddRef,p) +#define IPropertyPage2_Release(p) ICOM_CALL (Release,p) +/*** IPropertyPage methods ***/ +#define IPropertyPage2_SetPageSite(p,a) ICOM_CALL1(SetPageSite,p,a) +#define IPropertyPage2_Activate(p,a,b,c) ICOM_CALL3(Activate,p,a,b,c) +#define IPropertyPage2_Deactivate(p) ICOM_CALL (Deactivate,p) +#define IPropertyPage2_GetPageInfo(p,a) ICOM_CALL1(GetPageInfo,p,a) +#define IPropertyPage2_SetObjects(p,a,b) ICOM_CALL2(SetObjects,p,a,b) +#define IPropertyPage2_Show(p,a) ICOM_CALL1(Show,p,a) +#define IPropertyPage2_Move(p,a) ICOM_CALL1(Move,p,a) +#define IPropertyPage2_IsPageDirty(p) ICOM_CALL (IsPageDirty,p) +#define IPropertyPage2_Apply(p) ICOM_CALL (Apply,p) +#define IPropertyPage2_Help(p,a) ICOM_CALL1(Help,p,a) +#define IPropertyPage2_TranslateAccelerator(p,a) ICOM_CALL1(TranslateAccelerator,p,a) +/*** IPropertyPage2 methods ***/ +#define IPropertyPage2_EditProperty(p,a) ICOM_CALL1(EditProperty,p,a) + + +/***************************************************************************** + * IPropertPageSite interface + */ +#define ICOM_INTERFACE IPropertyPageSite +#define IPropertyPageSite_METHODS \ + ICOM_METHOD1(HRESULT,OnStatusChange, DWORD,dwFlags) \ + ICOM_METHOD1(HRESULT,GetLocaleID, LCID*,pLocaleID) \ + ICOM_METHOD1(HRESULT,GetPageContainer, IUnknown**,ppUnk) \ + ICOM_METHOD1(HRESULT,TranslateAccelerator, MSG*,pMsg) +#define IPropertyPageSite_IMETHODS \ + IUnknown_IMETHODS \ + IPropertyPageSite_METHODS +ICOM_DEFINE(IPropertyPageSite,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPropertyPageSite_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPropertyPageSite_AddRef(p) ICOM_CALL (AddRef,p) +#define IPropertyPageSite_Release(p) ICOM_CALL (Release,p) +/*** IPropertyPageSite methods ***/ +#define IPropertyPageSite_OnStatusChange(p,a) ICOM_CALL1(OnStatusChange,p,a) +#define IPropertyPageSite_GetLocaleID(p,a) ICOM_CALL1(GetLocaleID,p,a) +#define IPropertyPageSite_GetPageContainer(p,a) ICOM_CALL1(GetPageContainer,p,a) +#define IPropertyPageSite_TranslateAccelerator(p,a) ICOM_CALL1(TranslateAccelerator,p,a) + + +/***************************************************************************** + * IPropertyNotifySink interface + */ +#define ICOM_INTERFACE IPropertyNotifySink +#define IPropertyNotifySink_METHODS \ + ICOM_METHOD1(HRESULT,OnChanged, DISPID,dispID) \ + ICOM_METHOD1(HRESULT,OnRequestEdit, DISPID,dispID) +#define IPropertyNotifySink_IMETHODS \ + IUnknown_IMETHODS \ + IPropertyNotifySink_METHODS +ICOM_DEFINE(IPropertyNotifySink,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPropertyNotifySink_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPropertyNotifySink_AddRef(p) ICOM_CALL (AddRef,p) +#define IPropertyNotifySink_Release(p) ICOM_CALL (Release,p) +/*** IPropertyNotifySink methods ***/ +#define IPropertyNotifySink_OnChanged(p,a) ICOM_CALL1(OnChanged,p,a) +#define IPropertyNotifySink_OnRequestEdit(p,a) ICOM_CALL1(OnRequestEdit,p,a) + + +/***************************************************************************** + * IPropertyNotifySink interface + */ +#define ICOM_INTERFACE ISimpleFrameSite +#define ISimpleFrameSite_METHODS \ + ICOM_METHOD6(HRESULT,PreMessageFilter, HWND,hWnd, UINT,msg, WPARAM,wp, LPARAM,lp, LRESULT*,plResult, DWORD*,pwdCookie) \ + ICOM_METHOD6(HRESULT,PostMessageFilter, HWND,hWnd, UINT,msg, WPARAM,wp, LPARAM,lp, LRESULT*,plResult, DWORD,pwdCookie) +#define ISimpleFrameSite_IMETHODS \ + IUnknown_IMETHODS \ + ISimpleFrameSite_METHODS +ICOM_DEFINE(ISimpleFrameSite,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ISimpleFrameSite_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ISimpleFrameSite_AddRef(p) ICOM_CALL (AddRef,p) +#define ISimpleFrameSite_Release(p) ICOM_CALL (Release,p) +/*** IPropertyNotifySink methods ***/ +#define ISimpleFrameSite_PreMessageFilter(p,a,b,c,d,e,f) ICOM_CALL1(PreMessageFilter,p,a,b,c,d,e,f) +#define ISimpleFrameSite_PostMessageFilter(p,a,b,c,d,e,f) ICOM_CALL1(PostMessageFilter,p,a,b,c,d,e,f) + + +/***************************************************************************** + * IPersistStreamInit interface + */ +#define ICOM_INTERFACE IPersistStreamInit +#define IPersistStreamInit_METHODS \ + ICOM_METHOD (HRESULT,IsDirty) \ + ICOM_METHOD1(HRESULT,Load, LPSTREAM,pStm) \ + ICOM_METHOD2(HRESULT,Save, LPSTREAM,pStm, BOOL,fClearDirty) \ + ICOM_METHOD1(HRESULT,GetSizeMax, ULARGE_INTEGER*,pcbSize) \ + ICOM_METHOD (HRESULT,InitNew) +#define IPersistStreamInit_IMETHODS \ + IPersist_IMETHODS \ + IPersistStreamInit_METHODS +ICOM_DEFINE(IPersistStreamInit,IPersist) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPersistStreamInit_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPersistStreamInit_AddRef(p) ICOM_CALL (AddRef,p) +#define IPersistStreamInit_Release(p) ICOM_CALL (Release,p) +/*** IPersist methods ***/ +#define IPersistStreamInit_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) +/*** IPersistStreamInit methods ***/ +#define IPersistStreamInit_IsDirty(p) ICOM_CALL (IsDirty,p) +#define IPersistStreamInit_Load(p,a) ICOM_CALL1(Load,p,a) +#define IPersistStreamInit_Save(p,a,b) ICOM_CALL2(Save,p,a,b) +#define IPersistStreamInit_GetSizeMax(p,a) ICOM_CALL1(GetSizeMax,p,a) +#define IPersistStreamInit_InitNew(p) ICOM_CALL (InitNew,p) + + +/***************************************************************************** + * IPersistMemory interface + */ +#define ICOM_INTERFACE IPersistMemory +#define IPersistMemory_METHODS \ + ICOM_METHOD (HRESULT,IsDirty) \ + ICOM_METHOD2(HRESULT,Load, LPVOID,pMem, ULONG,cbSize) \ + ICOM_METHOD3(HRESULT,Save, LPVOID,pMem, BOOL,fClearDirty, ULONG,cbSize) \ + ICOM_METHOD1(HRESULT,GetSizeMax, ULONG*,pCbSize) \ + ICOM_METHOD (HRESULT,InitNew) +#define IPersistMemory_IMETHODS \ + IPersist_IMETHODS \ + IPersistMemory_METHODS +ICOM_DEFINE(IPersistMemory,IPersist) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPersistMemory_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPersistMemory_AddRef(p) ICOM_CALL (AddRef,p) +#define IPersistMemory_Release(p) ICOM_CALL (Release,p) +/*** IPersist methods ***/ +#define IPersistMemory_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) +/*** IPersistMemory methods ***/ +#define IPersistMemory_IsDirty(p) ICOM_CALL (IsDirty,p) +#define IPersistMemory_Load(p,a,b) ICOM_CALL2(Load,p,a,b) +#define IPersistMemory_Save(p,a,b,c) ICOM_CALL3(Save,p,a,b,c) +#define IPersistMemory_GetSizeMax(p,a) ICOM_CALL1(GetSizeMax,p,a) +#define IPersistMemory_InitNew(p) ICOM_CALL (InitNew,p) + + +/***************************************************************************** + * IPersistPropertyBag interface + */ +#define ICOM_INTERFACE IPersistPropertyBag +#define IPersistPropertyBag_METHODS \ + ICOM_METHOD (HRESULT,InitNew) \ + ICOM_METHOD2(HRESULT,Load, IPropertyBag*,pPropBag, IErrorLog*,pErrorLog) \ + ICOM_METHOD3(HRESULT,Save, IPropertyBag*,pPropBag, BOOL,fClearDirty, BOOL,fSaveAllProperties) +#define IPersistPropertyBag_IMETHODS \ + IPersist_IMETHODS \ + IPersistPropertyBag_METHODS +ICOM_DEFINE(IPersistPropertyBag,IPersist) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPersistPropertyBag_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPersistPropertyBag_AddRef(p) ICOM_CALL (AddRef,p) +#define IPersistPropertyBag_Release(p) ICOM_CALL (Release,p) +/*** IPersist methods ***/ +#define IPersistPropertyBag_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) +/*** IPersistPropertyBag methods ***/ +#define IPersistPropertyBag_InitNew(p) ICOM_CALL (InitNew,p) +#define IPersistPropertyBag_Load(p,a,b) ICOM_CALL2(Load,p,a,b) +#define IPersistPropertyBag_Save(p,a,b,c) ICOM_CALL3(Save,p,a,b,c) + + +/***************************************************************************** + * IErrorLog interface + */ +#define ICOM_INTERFACE IErrorLog +#define IErrorLog_METHODS \ + ICOM_METHOD2(HRESULT,AddError, LPCOLESTR,pszPropName, EXCEPINFO*,pExcepInfo) +#define IErrorLog_IMETHODS \ + IUnknown_IMETHODS \ + IErrorLog_METHODS +ICOM_DEFINE(IErrorLog,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IErrorLog_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IErrorLog_AddRef(p) ICOM_CALL (AddRef,p) +#define IErrorLog_Release(p) ICOM_CALL (Release,p) +/*** IErrorLog methods ***/ +#define IErrorLog_AddError(p,a,b) ICOM_CALL2(GetClassID,p,a,b) + + +/***************************************************************************** + * IPropertyBag interface + */ +#define ICOM_INTERFACE IPropertyBag +#define IPropertyBag_METHODS \ + ICOM_METHOD3(HRESULT,Read, LPCOLESTR,pszPropName, VARIANT*,pVar, IErrorLog*,pErrorLog) \ + ICOM_METHOD2(HRESULT,Write, LPCOLESTR,pszPropName, VARIANT*,pVar) +#define IPropertyBag_IMETHODS \ + IUnknown_IMETHODS \ + IPropertyBag_METHODS +ICOM_DEFINE(IPropertyBag,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPropertyBag_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPropertyBag_AddRef(p) ICOM_CALL (AddRef,p) +#define IPropertyBag_Release(p) ICOM_CALL (Release,p) +/*** IPropertyBag methods ***/ +#define IPropertyBag_Read(p,a,b,c) ICOM_CALL3(Read,p,a,b,c) +#define IPropertyBag_Write(p,a,b) ICOM_CALL2(Write,p,a,b) + + +/***************************************************************************** + * ISpecifyPropertyPages interface + */ +#define ICOM_INTERFACE ISpecifyPropertyPages +#define ISpecifyPropertyPages_METHODS \ + ICOM_METHOD1(HRESULT,GetPages, CAUUID*,pPages) +#define ISpecifyPropertyPages_IMETHODS \ + IUnknown_IMETHODS \ + ISpecifyPropertyPages_METHODS +ICOM_DEFINE(ISpecifyPropertyPages,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ISpecifyPropertyPages_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ISpecifyPropertyPages_AddRef(p) ICOM_CALL (AddRef,p) +#define ISpecifyPropertyPages_Release(p) ICOM_CALL (Release,p) +/*** ISpecifyPropertyPages methods ***/ +#define ISpecifyPropertyPages_GetPages(p,a) ICOM_CALL3(GetPages,p,a) + + +/***************************************************************************** + * IPerPropertyBrowsing interface + */ +#define ICOM_INTERFACE IPerPropertyBrowsing +#define IPerPropertyBrowsing_METHODS \ + ICOM_METHOD2(HRESULT,GetDisplayString, DISPID,dispID, BSTR*,pBstr) \ + ICOM_METHOD2(HRESULT,MapPropertyToPage, DISPID,dispID, CLSID*,pClsid) \ + ICOM_METHOD3(HRESULT,GetPredefinedStrings, DISPID,dispID, CALPOLESTR*,pCaStringsOut, CADWORD*,pCaCookiesOut) \ + ICOM_METHOD3(HRESULT,GetPredefinedValue, DISPID,dispID, DWORD,dwCookie, VARIANT*,pVarOut) +#define IPerPropertyBrowsing_IMETHODS \ + IUnknown_IMETHODS \ + IPerPropertyBrowsing_METHODS +ICOM_DEFINE(IPerPropertyBrowsing,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPerPropertyBrowsing_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPerPropertyBrowsing_AddRef(p) ICOM_CALL (AddRef,p) +#define IPerPropertyBrowsing_Release(p) ICOM_CALL (Release,p) +/*** IPerPropertyBrowsing methods ***/ +#define IPerPropertyBrowsing_GetDisplayString(p,a,b) ICOM_CALL2(GetDisplayString,p,a,b) +#define IPerPropertyBrowsing_MapPropertyToPage(p,a,b) ICOM_CALL2(MapPropertyToPage,p,a,b) +#define IPerPropertyBrowsing_GetPredefinedStrings(p,a,b,c) ICOM_CALL3(GetPredefinedStrings,p,a,b,c) +#define IPerPropertyBrowsing_GetPredefinedValue(p,a,b,c) ICOM_CALL3(GetPredefinedValue,p,a,b,c) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_PROPERTY_H */ + diff --git a/reactos/include/ole32/obj_propertystorage.h b/reactos/include/ole32/obj_propertystorage.h new file mode 100644 index 00000000000..5236ff9ae3c --- /dev/null +++ b/reactos/include/ole32/obj_propertystorage.h @@ -0,0 +1,438 @@ +/* + * Defines the COM interfaces and APIs related to saving properties to file. + */ + +#ifndef __WINE_WINE_OBJ_PROPERTYSTORAGE_H +#define __WINE_WINE_OBJ_PROPERTYSTORAGE_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IEnumSTATPROPSETSTG, 0x0000013bL, 0, 0); +typedef struct IEnumSTATPROPSETSTG IEnumSTATPROPSETSTG,*LPENUMSTATPROPSETSTG; + +DEFINE_OLEGUID(IID_IEnumSTATPROPSTG, 0x00000139L, 0, 0); +typedef struct IEnumSTATPROPSTG IEnumSTATPROPSTG,*LPENUMSTATPROPSTG; + +DEFINE_OLEGUID(IID_IPropertySetStorage, 0x0000013aL, 0, 0); +typedef struct IPropertySetStorage IPropertySetStorage,*LPPROPERTYSETSTORAGE; + +DEFINE_OLEGUID(IID_IPropertyStorage, 0x00000138L, 0, 0); +typedef struct IPropertyStorage IPropertyStorage,*LPPROPERTYSTORAGE; + + +/***************************************************************************** + * Predeclare the structures + */ + +typedef struct tagSTATPROPSETSTG STATPROPSETSTG; +typedef struct tagSTATPROPSTG STATPROPSTG; + +extern const FMTID FMTID_SummaryInformation; +extern const FMTID FMTID_DocSummaryInformation; +extern const FMTID FMTID_UserDefinedProperties; + +/***************************************************************************** + * PROPSPEC structure + */ + +/* Reserved global Property IDs */ +#define PID_DICTIONARY ( 0 ) + +#define PID_CODEPAGE ( 0x1 ) + +#define PID_FIRST_USABLE ( 0x2 ) + +#define PID_FIRST_NAME_DEFAULT ( 0xfff ) + +#define PID_LOCALE ( 0x80000000 ) + +#define PID_MODIFY_TIME ( 0x80000001 ) + +#define PID_SECURITY ( 0x80000002 ) + +#define PID_ILLEGAL ( 0xffffffff ) + +/* Property IDs for the SummaryInformation Property Set */ + +#define PIDSI_TITLE 0x00000002L /* VT_LPSTR */ +#define PIDSI_SUBJECT 0x00000003L /* VT_LPSTR */ +#define PIDSI_AUTHOR 0x00000004L /* VT_LPSTR */ +#define PIDSI_KEYWORDS 0x00000005L /* VT_LPSTR */ +#define PIDSI_COMMENTS 0x00000006L /* VT_LPSTR */ +#define PIDSI_TEMPLATE 0x00000007L /* VT_LPSTR */ +#define PIDSI_LASTAUTHOR 0x00000008L /* VT_LPSTR */ +#define PIDSI_REVNUMBER 0x00000009L /* VT_LPSTR */ +#define PIDSI_EDITTIME 0x0000000aL /* VT_FILETIME (UTC) */ +#define PIDSI_LASTPRINTED 0x0000000bL /* VT_FILETIME (UTC) */ +#define PIDSI_CREATE_DTM 0x0000000cL /* VT_FILETIME (UTC) */ +#define PIDSI_LASTSAVE_DTM 0x0000000dL /* VT_FILETIME (UTC) */ +#define PIDSI_PAGECOUNT 0x0000000eL /* VT_I4 */ +#define PIDSI_WORDCOUNT 0x0000000fL /* VT_I4 */ +#define PIDSI_CHARCOUNT 0x00000010L /* VT_I4 */ +#define PIDSI_THUMBNAIL 0x00000011L /* VT_CF */ +#define PIDSI_APPNAME 0x00000012L /* VT_LPSTR */ +#define PIDSI_DOC_SECURITY 0x00000013L /* VT_I4 */ +#define PRSPEC_INVALID ( 0xffffffff ) + + +#define PRSPEC_LPWSTR ( 0 ) +#define PRSPEC_PROPID ( 1 ) + +typedef struct tagPROPSPEC +{ + ULONG ulKind; + union + { + PROPID propid; + LPOLESTR lpwstr; + } u; +} PROPSPEC; + + +/***************************************************************************** + * STATPROPSETSTG structure + */ +/* Macros for parsing the OS Version of the Property Set Header */ +#define PROPSETHDR_OSVER_KIND(dwOSVer) HIWORD( (dwOSVer) ) +#define PROPSETHDR_OSVER_MAJOR(dwOSVer) LOBYTE(LOWORD( (dwOSVer) )) +#define PROPSETHDR_OSVER_MINOR(dwOSVer) HIBYTE(LOWORD( (dwOSVer) )) +#define PROPSETHDR_OSVERSION_UNKNOWN 0xFFFFFFFF + +struct tagSTATPROPSETSTG +{ + FMTID fmtid; + CLSID clsid; + DWORD grfFlags; + FILETIME mtime; + FILETIME ctime; + FILETIME atime; + DWORD dwOSVersion; +}; + + +/***************************************************************************** + * STATPROPSTG structure + */ +struct tagSTATPROPSTG +{ + LPOLESTR lpwstrName; + PROPID propid; + VARTYPE vt; +}; + + +/***************************************************************************** + * IEnumSTATPROPSETSTG interface + */ +#define ICOM_INTERFACE IEnumSTATPROPSETSTG +#define IEnumSTATPROPSETSTG_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, STATPROPSETSTG*,rgelt, ULONG*,pceltFethed) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumSTATPROPSETSTG**,ppenum) +#define IEnumSTATPROPSETSTG_IMETHODS \ + IUnknown_IMETHODS \ + IEnumSTATPROPSETSTG_METHODS +ICOM_DEFINE(IEnumSTATPROPSETSTG,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumSTATPROPSETSTG_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumSTATPROPSETSTG_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumSTATPROPSETSTG_Release(p) ICOM_CALL (Release,p) +/*** IEnumSTATPROPSETSTG methods ***/ +#define IEnumSTATPROPSETSTG_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumSTATPROPSETSTG_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumSTATPROPSETSTG_Reset(p) ICOM_CALL (Reset,p) +#define IEnumSTATPROPSETSTG_Clone(p,a) ICOM_CALL1(Clone,p,a) + + +/***************************************************************************** + * IEnumSTATPROPSTG interface + */ +#define ICOM_INTERFACE IEnumSTATPROPSTG +#define IEnumSTATPROPSTG_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, STATPROPSTG*,rgelt, ULONG*,pceltFethed) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumSTATPROPSTG**,ppenum) +#define IEnumSTATPROPSTG_IMETHODS \ + IUnknown_IMETHODS \ + IEnumSTATPROPSTG_METHODS +ICOM_DEFINE(IEnumSTATPROPSTG,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumSTATPROPSTG_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumSTATPROPSTG_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumSTATPROPSTG_Release(p) ICOM_CALL (Release,p) +/*** IEnumSTATPROPSTG methods ***/ +#define IEnumSTATPROPSTG_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumSTATPROPSTG_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumSTATPROPSTG_Reset(p) ICOM_CALL (Reset,p) +#define IEnumSTATPROPSTG_Clone(p,a) ICOM_CALL1(Clone,p,a) + + +/***************************************************************************** + * IPropertySetStorage interface + */ +#define ICOM_INTERFACE IPropertySetStorage +#define IPropertySetStorage_METHODS \ + ICOM_METHOD5(HRESULT,Create, REFFMTID,rfmtid, const CLSID*,pclsid, DWORD,grfFlags, DWORD,grfMode, IPropertyStorage**,ppprstg) \ + ICOM_METHOD3(HRESULT,Open, REFFMTID,rfmtid, DWORD,grfMode, IPropertyStorage**,ppprstg) \ + ICOM_METHOD1(HRESULT,Delete, REFFMTID,rfmtid) \ + ICOM_METHOD1(HRESULT,Enum, IEnumSTATPROPSETSTG**,ppenum) +#define IPropertySetStorage_IMETHODS \ + IUnknown_IMETHODS \ + IPropertySetStorage_METHODS +ICOM_DEFINE(IPropertySetStorage,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPropertySetStorage_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPropertySetStorage_AddRef(p) ICOM_CALL (AddRef,p) +#define IPropertySetStorage_Release(p) ICOM_CALL (Release,p) +/*** IPropertySetStorage methods ***/ +#define IPropertySetStorage_Create(p,a,b,c,d,e) ICOM_CALL5(Create,p,a,b,c,d,e) +#define IPropertySetStorage_Open(p,a,b,c) ICOM_CALL3(Open,p,a,b,c) +#define IPropertySetStorage_Delete(p,a) ICOM_CALL1(Delete,p,a) +#define IPropertySetStorage_Enum(p,a) ICOM_CALL1(Enum,p,a) + + +/***************************************************************************** + * IPropertyStorage interface + */ +typedef struct tagPROPVARIANT PROPVARIANT,*LPPROPVARIANT; + +/* Flags for IPropertySetStorage::Create */ +#define PROPSETFLAG_DEFAULT ( 0 ) +#define PROPSETFLAG_NONSIMPLE ( 1 ) +#define PROPSETFLAG_ANSI ( 2 ) + +typedef struct tagCAUB +{ + ULONG cElems; + unsigned char *pElems; +} CAUB; + +typedef struct tagCAI +{ + ULONG cElems; + short *pElems; +} CAI; + +typedef struct tagCAUI +{ + ULONG cElems; + USHORT *pElems; +} CAUI; + +typedef struct tagCAL +{ + ULONG cElems; + long *pElems; +} CAL; + +typedef struct tagCAUL +{ + ULONG cElems; + ULONG *pElems; +} CAUL; + +typedef struct tagCAFLT +{ + ULONG cElems; + float *pElems; +} CAFLT; + +typedef struct tagCADBL +{ + ULONG cElems; + double *pElems; +} CADBL; + +typedef struct tagCACY +{ + ULONG cElems; + CY *pElems; +} CACY; + +typedef struct tagCADATE +{ + ULONG cElems; + DATE *pElems; +} CADATE; + +typedef struct tagCABSTR +{ + ULONG cElems; + BSTR *pElems; +} CABSTR; + +typedef struct tagCABOOL +{ + ULONG cElems; + VARIANT_BOOL *pElems; +} CABOOL; + +typedef struct tagCASCODE +{ + ULONG cElems; + SCODE *pElems; +} CASCODE; + +typedef struct tagCAPROPVARIANT +{ + ULONG cElems; + PROPVARIANT *pElems; +} CAPROPVARIANT; + +typedef struct tagCAH +{ + ULONG cElems; + LARGE_INTEGER *pElems; +} CAH; + +typedef struct tagCAUH +{ + ULONG cElems; + ULARGE_INTEGER *pElems; +} CAUH; + +typedef struct tagCALPSTR +{ + ULONG cElems; + LPSTR *pElems; +} CALPSTR; + +typedef struct tagCALPWSTR +{ + ULONG cElems; + LPWSTR *pElems; +} CALPWSTR; + +typedef struct tagCAFILETIME +{ + ULONG cElems; + FILETIME *pElems; +} CAFILETIME; + +typedef struct tagCACLIPDATA +{ + ULONG cElems; + CLIPDATA *pElems; +} CACLIPDATA; + +typedef struct tagCACLSID +{ + ULONG cElems; + CLSID *pElems; +} CACLSID; + +struct tagPROPVARIANT +{ + VARTYPE vt; + WORD wReserved1; + WORD wReserved2; + WORD wReserved3; + union + { + /* Empty union arm */ + UCHAR bVal; + short iVal; + USHORT uiVal; + VARIANT_BOOL boolVal; +#ifndef __cplusplus + /* FIXME: bool is reserved in C++, how can we deal with that ? */ + _VARIANT_BOOL bool; +#endif + long lVal; + ULONG ulVal; + float fltVal; + SCODE scode; + LARGE_INTEGER hVal; + ULARGE_INTEGER uhVal; + double dblVal; + CY cyVal; + DATE date; + FILETIME filetime; + CLSID *puuid; + BLOB blob; + CLIPDATA *pclipdata; + IStream *pStream; + IStorage *pStorage; + BSTR bstrVal; + LPSTR pszVal; + LPWSTR pwszVal; + CAUB caub; + CAI cai; + CAUI caui; + CABOOL cabool; + CAL cal; + CAUL caul; + CAFLT caflt; + CASCODE cascode; + CAH cah; + CAUH cauh; + CADBL cadbl; + CACY cacy; + CADATE cadate; + CAFILETIME cafiletime; + CACLSID cauuid; + CACLIPDATA caclipdata; + CABSTR cabstr; + CALPSTR calpstr; + CALPWSTR calpwstr; + CAPROPVARIANT capropvar; + } u; +}; + + +#define ICOM_INTERFACE IPropertyStorage +#define IPropertyStorage_METHODS \ + ICOM_METHOD3(HRESULT,ReadMultiple, ULONG,cpspec, const PROPSPEC*,rgpspec, PROPVARIANT*,rgpropvar) \ + ICOM_METHOD4(HRESULT,WriteMultiple, ULONG,cpspec, const PROPSPEC*,rgpspec, const PROPVARIANT*,rgpropvar, PROPID,propidNameFirst) \ + ICOM_METHOD2(HRESULT,DeleteMultiple, ULONG,cpspec, const PROPSPEC*,rgpspec) \ + ICOM_METHOD2(HRESULT,ReadPropertyNames, const PROPID*,rgpropid, LPOLESTR*,rglpwstrName) \ + ICOM_METHOD3(HRESULT,WritePropertyNames, ULONG,cpropid, const PROPID*,rgpropid, LPOLESTR*,rglpwstrName) \ + ICOM_METHOD2(HRESULT,DeletePropertyNames, ULONG,cpropid, const PROPID*,rgpropid) \ + ICOM_METHOD1(HRESULT,Commit, DWORD,grfCommitFlags) \ + ICOM_METHOD (HRESULT,Revert) \ + ICOM_METHOD1(HRESULT,Enum, IEnumSTATPROPSTG**,ppenum) \ + ICOM_METHOD3(HRESULT,SetTimes, const FILETIME*,pctime, const FILETIME*,patime, const FILETIME*,pmtime) \ + ICOM_METHOD1(HRESULT,SetClass, REFCLSID,clsid) \ + ICOM_METHOD1(HRESULT,Stat, STATPROPSETSTG*,pstatpsstg) +#define IPropertyStorage_IMETHODS \ + IUnknown_IMETHODS \ + IPropertyStorage_METHODS +ICOM_DEFINE(IPropertyStorage,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPropertyStorage_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPropertyStorage_AddRef(p) ICOM_CALL (AddRef,p) +#define IPropertyStorage_Release(p) ICOM_CALL (Release,p) +/*** IPropertyStorage methods ***/ +#define IPropertyStorage_ReadMultiple(p,a,b,c) ICOM_CALL3(ReadMultiple,p,a,b,c) +#define IPropertyStorage_WriteMultiple(p,a,b,c,d) ICOM_CALL4(WriteMultiple,p,a,b,c,d) +#define IPropertyStorage_DeleteMultiple(p,a,b) ICOM_CALL2(DeleteMultiple,p,a,b) +#define IPropertyStorage_ReadPropertyNames(p,a,b) ICOM_CALL2(ReadPropertyNames,p,a,b) +#define IPropertyStorage_WritePropertyNames(p,a,b,c) ICOM_CALL3(WritePropertyNames,p,a,b,c) +#define IPropertyStorage_DeletePropertyNames(p,a,b) ICOM_CALL2(DeletePropertyNames,p,a,b) +#define IPropertyStorage_Commit(p,a) ICOM_CALL1(Commit,p,a) +#define IPropertyStorage_Revert(p) ICOM_CALL (Revert,p) +#define IPropertyStorage_Enum(p,a) ICOM_CALL1(Enum,p,a) +#define IPropertyStorage_SetTimes(p,a,b,c) ICOM_CALL3(SetTimes,p,a,b,c) +#define IPropertyStorage_SetClass(p,a) ICOM_CALL1(SetClass,p,a) +#define IPropertyStorage_Stat(p,a) ICOM_CALL1(Stat,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_PROPERTYSTORAGE_H */ diff --git a/reactos/include/ole32/obj_queryassociations.h b/reactos/include/ole32/obj_queryassociations.h new file mode 100644 index 00000000000..257d9f231e5 --- /dev/null +++ b/reactos/include/ole32/obj_queryassociations.h @@ -0,0 +1,94 @@ +/************************************************************ + * IQueryAssociations + */ + +#ifndef __WINE_WINE_OBJ_QUERYASSOCIATIONS_H +#define __WINE_WINE_OBJ_QUERYASSOCIATIONS_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +DEFINE_GUID(IID_IQueryAssociations, 0xc46ca590, 0x3c3f, 0x11d2, 0xbe, 0xe6, 0x00, 0x00, 0xf8, 0x05, 0xca, 0x57); + +typedef struct IQueryAssociations IQueryAssociations,*LPQUERYASSOCIATIONS; + +#define ASSOCF_INIT_BYEXENAME 0x00000002 +#define ASSOCF_OPEN_BYEXENAME 0x00000002 +#define ASSOCF_INIT_DEFAULTTOSTAR 0x00000004 +#define ASSOCF_INIT_DEFAULTTOFOLDER 0x00000008 +#define ASSOCF_NOUSERSETTINGS 0x00000010 +#define ASSOCF_NOTRUNCATE 0x00000020 +#define ASSOCF_VERIFY 0x00000040 +#define ASSOCF_REMAPRUNDLL 0x00000080 +#define ASSOCF_NOFIXUPS 0x00000100 +#define ASSOCF_IGNOREBASECLASS 0x00000200 + +typedef DWORD ASSOCF; + +typedef enum +{ + ASSOCSTR_COMMAND = 1, + ASSOCSTR_EXECUTABLE, + ASSOCSTR_FRIENDLYDOCNAME, + ASSOCSTR_FRIENDLYAPPNAME, + ASSOCSTR_NOOPEN, + ASSOCSTR_SHELLNEWVALUE, + ASSOCSTR_DDECOMMAND, + ASSOCSTR_DDEIFEXEC, + ASSOCSTR_DDEAPPLICATION, + ASSOCSTR_DDETOPIC, + ASSOCSTR_MAX +} ASSOCSTR; + +typedef enum +{ + ASSOCKEY_SHELLEXECCLASS = 1, + ASSOCKEY_APP, + ASSOCKEY_CLASS, + ASSOCKEY_BASECLASS, + ASSOCKEY_MAX +} ASSOCKEY; + +typedef enum +{ + ASSOCDATA_MSIDESCRIPTOR = 1, + ASSOCDATA_NOACTIVATEHANDLER, + ASSOCDATA_QUERYCLASSSTORE, + ASSOCDATA_HASPERUSERASSOC, + ASSOCDATA_MAX +} ASSOCDATA; + +typedef enum +{ + ASSOCENUM_NONE +} ASSOCENUM; + +#define ICOM_INTERFACE IQueryAssociations +#define IQueryAssociations_METHODS \ + ICOM_METHOD4 (HRESULT, Init, ASSOCF, flags, LPCWSTR, pszAssoc, HKEY, hkProgid, HWND, hwnd) \ + ICOM_METHOD5 (HRESULT, GetString, ASSOCF, flags, ASSOCSTR, str, LPCWSTR, pszExtra, LPWSTR, pszOut, DWORD*, pcchOut) \ + ICOM_METHOD4 (HRESULT, GetKey, ASSOCF, flags, ASSOCKEY, key, LPCWSTR, pszExtra, HKEY*, phkeyOut) \ + ICOM_METHOD5 (HRESULT, GetData, ASSOCF, flags, ASSOCDATA, data, LPCWSTR, pszExtra, LPVOID, pvOut, DWORD*, pcbOut) \ + ICOM_METHOD5 (HRESULT, GetEnum, ASSOCF, flags, ASSOCENUM, assocenum, LPCWSTR, pszExtra, REFIID, riid, LPVOID*, ppvOut) +#define IQueryAssociations_IMETHODS \ + IUnknown_IMETHODS \ + IQueryAssociations_METHODS +ICOM_DEFINE(IQueryAssociations,IUnknown) +#undef ICOM_INTERFACE + +#define IQueryAssociations_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IQueryAssociations_AddRef(p) ICOM_CALL(AddRef,p) +#define IQueryAssociations_Release(p) ICOM_CALL(Release,p) +#define IQueryAssociations_Init(p,a,b,c,d) ICOM_CALL4(Init,p,a,b,c,d) +#define IQueryAssociations_GetString(p,a,b,c,d,e) ICOM_CALL5(GetString,p,a,b,c,d,e) +#define IQueryAssociations_GetKey(p,a,b,c,d) ICOM_CALL4(GetKey,p,a,b,c,d) +#define IQueryAssociations_GetData(p,a,b,c,d,e) ICOM_CALL5(GetData,p,a,b,c,d,e) +#define IQueryAssociations_GetEnum(p,a,b,c,d,e) ICOM_CALL5(GetEnum,p,a,b,c,d,e) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_QUERYASSOCIATIONS_H */ + diff --git a/reactos/include/ole32/obj_serviceprovider.h b/reactos/include/ole32/obj_serviceprovider.h new file mode 100644 index 00000000000..0aef481fbe0 --- /dev/null +++ b/reactos/include/ole32/obj_serviceprovider.h @@ -0,0 +1,47 @@ +/* + * Defines the COM interfaces and APIs related to IServiceProvider + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_SERVICEPROVIDER_H +#define __WINE_WINE_OBJ_SERVICEPROVIDER_H + +#include "wine/obj_base.h" +#include "winbase.h" + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID(IID_IServiceProvider, 0x6d5140c1, 0x7436, 0x11ce, 0x80, 0x34, 0x00, 0xaa, 0x00, 0x60, 0x09, 0xfa); +typedef struct IServiceProvider IServiceProvider, *LPSERVICEPROVIDER; + + +/***************************************************************************** + * IServiceProvider interface + */ +#define ICOM_INTERFACE IServiceProvider +#define IServiceProvider_METHODS \ + ICOM_METHOD3( HRESULT, QueryService, REFGUID, guidService, REFIID, riid, void**, ppv) +#define IServiceProvider_IMETHODS \ + IUnknown_IMETHODS \ + IServiceProvider_METHODS +ICOM_DEFINE(IServiceProvider,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IServiceProvider_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IServiceProvider_AddRef(p) ICOM_CALL (AddRef,p) +#define IServiceProvider_Release(p) ICOM_CALL (Release,p) +/*** IServiceProvider methods ***/ +#define IServiceProvider_QueryService(p,a,b,c) ICOM_CALL3(QueryService,p,a,b,c) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_SERVICEPROVIDER_H */ diff --git a/reactos/include/ole32/obj_shellbrowser.h b/reactos/include/ole32/obj_shellbrowser.h new file mode 100644 index 00000000000..d3f902f618b --- /dev/null +++ b/reactos/include/ole32/obj_shellbrowser.h @@ -0,0 +1,99 @@ +/************************************************************ + * IShellBrowser + */ + +#ifndef __WINE_WINE_OBJ_SHELLBROWSER_H +#define __WINE_WINE_OBJ_SHELLBROWSER_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/* it's ok commented out, see obj_shellview.h + typedef struct IShellBrowser IShellBrowser, *LPSHELLBROWSER; +*/ + +#define SID_SShellBrowser IID_IShellBrowser + +DEFINE_GUID(SID_STopLevelBrowser, 0x4C96BE40L, 0x915C, 0x11CF, 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37); + +/* targets for GetWindow/SendControlMsg */ +#define FCW_STATUS 0x0001 +#define FCW_TOOLBAR 0x0002 +#define FCW_TREE 0x0003 +#define FCW_INTERNETBAR 0x0006 +#define FCW_PROGRESS 0x0008 + +/* wFlags for BrowseObject*/ +#define SBSP_DEFBROWSER 0x0000 +#define SBSP_SAMEBROWSER 0x0001 +#define SBSP_NEWBROWSER 0x0002 + +#define SBSP_DEFMODE 0x0000 +#define SBSP_OPENMODE 0x0010 +#define SBSP_EXPLOREMODE 0x0020 + +#define SBSP_ABSOLUTE 0x0000 +#define SBSP_RELATIVE 0x1000 +#define SBSP_PARENT 0x2000 +#define SBSP_NAVIGATEBACK 0x4000 +#define SBSP_NAVIGATEFORWARD 0x8000 + +#define SBSP_ALLOW_AUTONAVIGATE 0x10000 + +#define SBSP_INITIATEDBYHLINKFRAME 0x80000000 +#define SBSP_REDIRECT 0x40000000 +#define SBSP_WRITENOHISTORY 0x08000000 + +/* uFlage for SetToolbarItems */ +#define FCT_MERGE 0x0001 +#define FCT_CONFIGABLE 0x0002 +#define FCT_ADDTOEND 0x0004 + +#define ICOM_INTERFACE IShellBrowser +#define IShellBrowser_METHODS \ + ICOM_METHOD2(HRESULT, InsertMenusSB, HMENU, hmenuShared, LPOLEMENUGROUPWIDTHS, lpMenuWidths) \ + ICOM_METHOD3(HRESULT, SetMenuSB, HMENU, hmenuShared, HOLEMENU, holemenuReserved, HWND, hwndActiveObject) \ + ICOM_METHOD1(HRESULT, RemoveMenusSB, HMENU, hmenuShared) \ + ICOM_METHOD1(HRESULT, SetStatusTextSB, LPCOLESTR, lpszStatusText) \ + ICOM_METHOD1(HRESULT, EnableModelessSB, BOOL, fEnable) \ + ICOM_METHOD2(HRESULT, TranslateAcceleratorSB, LPMSG, lpmsg, WORD, wID) \ + ICOM_METHOD2(HRESULT, BrowseObject, LPCITEMIDLIST, pidl, UINT, wFlags) \ + ICOM_METHOD2(HRESULT, GetViewStateStream, DWORD, grfMode, LPSTREAM*, ppStrm) \ + ICOM_METHOD2(HRESULT, GetControlWindow, UINT, id, HWND*, lphwnd) \ + ICOM_METHOD5(HRESULT, SendControlMsg, UINT, id, UINT, uMsg, WPARAM, wParam, LPARAM, lParam, LRESULT*, pret) \ + ICOM_METHOD1(HRESULT, QueryActiveShellView, IShellView**, IShellView) \ + ICOM_METHOD1(HRESULT, OnViewWindowActive, IShellView*, IShellView) \ + ICOM_METHOD3(HRESULT, SetToolbarItems, LPTBBUTTON, lpButtons, UINT, nButtons, UINT, uFlags) +#define IShellBrowser_IMETHODS \ + IOleWindow_IMETHODS \ + IShellBrowser_METHODS +ICOM_DEFINE(IShellBrowser,IOleWindow) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IShellBrowser_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IShellBrowser_AddRef(p) ICOM_CALL(AddRef,p) +#define IShellBrowser_Release(p) ICOM_CALL(Release,p) +/*** IShellBrowser methods ***/ +#define IShellBrowser_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IShellBrowser_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +#define IShellBrowser_InsertMenusSB(p,a,b) ICOM_CALL2(InsertMenusSB,p,a,b) +#define IShellBrowser_SetMenuSB(p,a,b,c) ICOM_CALL3(SetMenuSB,p,a,b,c) +#define IShellBrowser_RemoveMenusSB(p,a) ICOM_CALL1(RemoveMenusSB,p,a) +#define IShellBrowser_SetStatusTextSB(p,a) ICOM_CALL1(SetStatusTextSB,p,a) +#define IShellBrowser_EnableModelessSB(p,a) ICOM_CALL1(EnableModelessSB,p,a) +#define IShellBrowser_TranslateAcceleratorSB(p,a,b) ICOM_CALL2(TranslateAcceleratorSB,p,a,b) +#define IShellBrowser_BrowseObject(p,a,b) ICOM_CALL2(BrowseObject,p,a,b) +#define IShellBrowser_GetViewStateStream(p,a,b) ICOM_CALL2(GetViewStateStream,p,a,b) +#define IShellBrowser_GetControlWindow(p,a,b) ICOM_CALL2(GetControlWindow,p,a,b) +#define IShellBrowser_SendControlMsg(p,a,b,c,d,e) ICOM_CALL5(SendControlMsg,p,a,b,c,d,e) +#define IShellBrowser_QueryActiveShellView(p,a) ICOM_CALL1(QueryActiveShellView,p,a) +#define IShellBrowser_OnViewWindowActive(p,a) ICOM_CALL1(OnViewWindowActive,p,a) +#define IShellBrowser_SetToolbarItems(p,a,b,c) ICOM_CALL3(SetToolbarItems,p,a,b,c) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_SHELLBROWSER_H */ diff --git a/reactos/include/ole32/obj_shellextinit.h b/reactos/include/ole32/obj_shellextinit.h new file mode 100644 index 00000000000..3bac3a1cd3d --- /dev/null +++ b/reactos/include/ole32/obj_shellextinit.h @@ -0,0 +1,34 @@ +/************************************************************ + * IShellExtInit + */ + +#ifndef __WINE_WINE_OBJ_SHELLEXTINIT_H +#define __WINE_WINE_OBJ_SHELLEXTINIT_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +typedef struct IShellExtInit IShellExtInit, *LPSHELLEXTINIT; + +#define ICOM_INTERFACE IShellExtInit +#define IShellExtInit_METHODS \ + ICOM_METHOD3(HRESULT, Initialize, LPCITEMIDLIST, pidlFolder, LPDATAOBJECT, lpdobj, HKEY, hkeyProgID) +#define IShellExtInit_IMETHODS \ + IUnknown_IMETHODS \ + IShellExtInit_METHODS +ICOM_DEFINE(IShellExtInit,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IShellExtInit_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IShellExtInit_AddRef(p) ICOM_CALL(AddRef,p) +#define IShellExtInit_Release(p) ICOM_CALL(Release,p) +/*** IShellExtInit methods ***/ +#define IShellExtInit_Initialize(p,a,b,c) ICOM_CALL3(Initialize,p,a,b,c) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_SHELLEXTINIT_H */ diff --git a/reactos/include/ole32/obj_shellfolder.h b/reactos/include/ole32/obj_shellfolder.h new file mode 100644 index 00000000000..0a2540321ac --- /dev/null +++ b/reactos/include/ole32/obj_shellfolder.h @@ -0,0 +1,356 @@ +/* + * Defines the COM interfaces and APIs related to IShellFolder + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_SHELLFOLDER_H +#define __WINE_WINE_OBJ_SHELLFOLDER_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/**************************************************************************** +* STRRET +*/ +#define STRRET_WSTR 0x0000 +#define STRRET_ASTR 0x0003 + +#define STRRET_OFFSETA 0x0001 +#define STRRET_OFFSETW 0x0004 +#define STRRET_OFFSET WINELIB_NAME_AW(STRRET_OFFSET) + +#define STRRET_CSTRA 0x0002 +#define STRRET_CSTRW 0x0005 +#define STRRET_CSTR WINELIB_NAME_AW(STRRET_CSTR) + +typedef struct _STRRET +{ UINT uType; /* STRRET_xxx */ + union + { LPWSTR pOleStr; /* OLESTR that will be freed */ + LPSTR pStr; + UINT uOffset; /* OffsetINT32o SHITEMID (ANSI) */ + char cStr[MAX_PATH]; /* Buffer to fill in */ + WCHAR cStrW[MAX_PATH]; + } DUMMYUNIONNAME; +} STRRET,*LPSTRRET; + +/***************************************************************************** + * Predeclare the interfaces + */ +typedef struct IShellFolder IShellFolder, *LPSHELLFOLDER; + +typedef struct IPersistFolder IPersistFolder, *LPPERSISTFOLDER; + +DEFINE_GUID(IID_IPersistFolder2, 0x1ac3d9f0L, 0x175C, 0x11D1, 0x95, 0xBE, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x4F); +typedef struct IPersistFolder2 IPersistFolder2, *LPPERSISTFOLDER2; + +DEFINE_GUID(IID_IShellFolder2, 0xB82C5AA8, 0xA41B, 0x11D2, 0xBE, 0x32, 0x0, 0xc0, 0x4F, 0xB9, 0x36, 0x61); +typedef struct IShellFolder2 IShellFolder2, *LPSHELLFOLDER2; + +DEFINE_GUID(IID_IEnumExtraSearch, 0xE700BE1, 0x9DB6, 0x11D1, 0xA1, 0xCE, 0x0, 0xc0, 0x4F, 0xD7, 0x5D, 0x13); +typedef struct IEnumExtraSearch IEnumExtraSearch, *LPENUMEXTRASEARCH; + +/***************************************************************************** + * IEnumExtraSearch interface + */ + +typedef struct +{ + GUID guidSearch; + WCHAR wszFriendlyName[80]; + WCHAR wszMenuText[80]; + WCHAR wszHelpText[MAX_PATH]; + WCHAR wszUrl[2084]; + WCHAR wszIcon[MAX_PATH+10]; + WCHAR wszGreyIcon[MAX_PATH+10]; + WCHAR wszClrIcon[MAX_PATH+10]; +} EXTRASEARCH,* LPEXTRASEARCH; + +#define ICOM_INTERFACE IEnumExtraSearch +#define IEnumExtraSearch_METHODS \ + ICOM_METHOD3(HRESULT, Next, ULONG, celt, LPEXTRASEARCH*, rgelt, ULONG*, pceltFetched) \ + ICOM_METHOD1(HRESULT, Skip, ULONG, celt) \ + ICOM_METHOD (HRESULT, Reset) \ + ICOM_METHOD1(HRESULT, Clone, IEnumExtraSearch**, ppenum) +#define IEnumExtraSearch_IMETHODS \ + IUnknown_IMETHODS \ + IEnumExtraSearch_METHODS +ICOM_DEFINE(IEnumExtraSearch,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumIDList_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumIDList_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumIDList_Release(p) ICOM_CALL (Release,p) +/*** IEnumIDList methods ***/ +#define IEnumIDList_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumIDList_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumIDList_Reset(p) ICOM_CALL(Reset,p) +#define IEnumIDList_Clone(p,a) ICOM_CALL1(Clone,p,a) + +/***************************************************************************** + * IShellFolder::GetDisplayNameOf/SetNameOf uFlags + */ +typedef enum +{ SHGDN_NORMAL = 0, /* default (display purpose) */ + SHGDN_INFOLDER = 1, /* displayed under a folder (relative)*/ + SHGDN_FORPARSING = 0x8000 /* for ParseDisplayName or path */ +} SHGNO; + +/***************************************************************************** + * IShellFolder::EnumObjects + */ +typedef enum tagSHCONTF +{ SHCONTF_FOLDERS = 32, /* for shell browser */ + SHCONTF_NONFOLDERS = 64, /* for default view */ + SHCONTF_INCLUDEHIDDEN = 128 /* for hidden/system objects */ +} SHCONTF; + +/***************************************************************************** + * IShellFolder::GetAttributesOf flags + */ +#define SFGAO_CANCOPY DROPEFFECT_COPY /* Objects can be copied */ +#define SFGAO_CANMOVE DROPEFFECT_MOVE /* Objects can be moved */ +#define SFGAO_CANLINK DROPEFFECT_LINK /* Objects can be linked */ +#define SFGAO_CANRENAME 0x00000010L /* Objects can be renamed */ +#define SFGAO_CANDELETE 0x00000020L /* Objects can be deleted */ +#define SFGAO_HASPROPSHEET 0x00000040L /* Objects have property sheets */ +#define SFGAO_DROPTARGET 0x00000100L /* Objects are drop target */ +#define SFGAO_CAPABILITYMASK 0x00000177L +#define SFGAO_LINK 0x00010000L /* Shortcut (link) */ +#define SFGAO_SHARE 0x00020000L /* shared */ +#define SFGAO_READONLY 0x00040000L /* read-only */ +#define SFGAO_GHOSTED 0x00080000L /* ghosted icon */ +#define SFGAO_HIDDEN 0x00080000L /* hidden object */ +#define SFGAO_DISPLAYATTRMASK 0x000F0000L +#define SFGAO_FILESYSANCESTOR 0x10000000L /* It contains file system folder */ +#define SFGAO_FOLDER 0x20000000L /* It's a folder. */ +#define SFGAO_FILESYSTEM 0x40000000L /* is a file system thing (file/folder/root) */ +#define SFGAO_HASSUBFOLDER 0x80000000L /* Expandable in the map pane */ +#define SFGAO_CONTENTSMASK 0x80000000L +#define SFGAO_VALIDATE 0x01000000L /* invalidate cached information */ +#define SFGAO_REMOVABLE 0x02000000L /* is this removeable media? */ +#define SFGAO_BROWSABLE 0x08000000L /* is in-place browsable */ +#define SFGAO_NONENUMERATED 0x00100000L /* is a non-enumerated object */ +#define SFGAO_NEWCONTENT 0x00200000L /* should show bold in explorer tree */ + +/************************************************************************ + * + * FOLDERSETTINGS +*/ + +typedef LPBYTE LPVIEWSETTINGS; + +/* NB Bitfields. */ +/* FWF_DESKTOP implies FWF_TRANSPARENT/NOCLIENTEDGE/NOSCROLL */ +typedef enum +{ FWF_AUTOARRANGE = 0x0001, + FWF_ABBREVIATEDNAMES = 0x0002, + FWF_SNAPTOGRID = 0x0004, + FWF_OWNERDATA = 0x0008, + FWF_BESTFITWINDOW = 0x0010, + FWF_DESKTOP = 0x0020, + FWF_SINGLESEL = 0x0040, + FWF_NOSUBFOLDERS = 0x0080, + FWF_TRANSPARENT = 0x0100, + FWF_NOCLIENTEDGE = 0x0200, + FWF_NOSCROLL = 0x0400, + FWF_ALIGNLEFT = 0x0800, + FWF_SINGLECLICKACTIVATE=0x8000 /* TEMPORARY -- NO UI FOR THIS */ +} FOLDERFLAGS; + +typedef enum +{ FVM_ICON = 1, + FVM_SMALLICON = 2, + FVM_LIST = 3, + FVM_DETAILS = 4 +} FOLDERVIEWMODE; + +typedef struct +{ UINT ViewMode; /* View mode (FOLDERVIEWMODE values) */ + UINT fFlags; /* View options (FOLDERFLAGS bits) */ +} FOLDERSETTINGS, *LPFOLDERSETTINGS; + +typedef const FOLDERSETTINGS * LPCFOLDERSETTINGS; + +/************************************************************************ + * Desktopfolder + */ + +extern IShellFolder * pdesktopfolder; + +DWORD WINAPI SHGetDesktopFolder(IShellFolder * *); + +/***************************************************************************** + * IShellFolder interface + */ +#define ICOM_INTERFACE IShellFolder +#define IShellFolder_METHODS \ + ICOM_METHOD6( HRESULT, ParseDisplayName, HWND, hwndOwner,LPBC, pbcReserved, LPOLESTR, lpszDisplayName, ULONG *, pchEaten, LPITEMIDLIST *, ppidl, ULONG *, pdwAttributes) \ + ICOM_METHOD3( HRESULT, EnumObjects, HWND, hwndOwner, DWORD, grfFlags, LPENUMIDLIST *, ppenumIDList)\ + ICOM_METHOD4( HRESULT, BindToObject, LPCITEMIDLIST, pidl, LPBC, pbcReserved, REFIID, riid, LPVOID *, ppvOut)\ + ICOM_METHOD4( HRESULT, BindToStorage, LPCITEMIDLIST, pidl, LPBC, pbcReserved, REFIID, riid, LPVOID *, ppvObj)\ + ICOM_METHOD3( HRESULT, CompareIDs, LPARAM, lParam, LPCITEMIDLIST, pidl1, LPCITEMIDLIST, pidl2)\ + ICOM_METHOD3( HRESULT, CreateViewObject, HWND, hwndOwner, REFIID, riid, LPVOID *, ppvOut)\ + ICOM_METHOD3( HRESULT, GetAttributesOf, UINT, cidl, LPCITEMIDLIST *, apidl, ULONG *, rgfInOut)\ + ICOM_METHOD6( HRESULT, GetUIObjectOf, HWND, hwndOwner, UINT, cidl, LPCITEMIDLIST *, apidl, REFIID, riid, UINT *, prgfInOut, LPVOID *, ppvOut)\ + ICOM_METHOD3( HRESULT, GetDisplayNameOf, LPCITEMIDLIST, pidl, DWORD, uFlags, LPSTRRET, lpName)\ + ICOM_METHOD5( HRESULT, SetNameOf, HWND, hwndOwner, LPCITEMIDLIST, pidl,LPCOLESTR, lpszName, DWORD, uFlags,LPITEMIDLIST *, ppidlOut) +#define IShellFolder_IMETHODS \ + IUnknown_IMETHODS \ + IShellFolder_METHODS +ICOM_DEFINE(IShellFolder,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IShellFolder_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IShellFolder_AddRef(p) ICOM_CALL (AddRef,p) +#define IShellFolder_Release(p) ICOM_CALL (Release,p) +/*** IShellFolder methods ***/ +#define IShellFolder_ParseDisplayName(p,a,b,c,d,e,f) ICOM_CALL6(ParseDisplayName,p,a,b,c,d,e,f) +#define IShellFolder_EnumObjects(p,a,b,c) ICOM_CALL3(EnumObjects,p,a,b,c) +#define IShellFolder_BindToObject(p,a,b,c,d) ICOM_CALL4(BindToObject,p,a,b,c,d) +#define IShellFolder_BindToStorage(p,a,b,c,d) ICOM_CALL4(BindToStorage,p,a,b,c,d) +#define IShellFolder_CompareIDs(p,a,b,c) ICOM_CALL3(CompareIDs,p,a,b,c) +#define IShellFolder_CreateViewObject(p,a,b,c) ICOM_CALL3(CreateViewObject,p,a,b,c) +#define IShellFolder_GetAttributesOf(p,a,b,c) ICOM_CALL3(GetAttributesOf,p,a,b,c) +#define IShellFolder_GetUIObjectOf(p,a,b,c,d,e,f) ICOM_CALL6(GetUIObjectOf,p,a,b,c,d,e,f) +#define IShellFolder_GetDisplayNameOf(p,a,b,c) ICOM_CALL3(GetDisplayNameOf,p,a,b,c) +#define IShellFolder_SetNameOf(p,a,b,c,d,e) ICOM_CALL5(SetNameOf,p,a,b,c,d,e) + +/***************************************************************************** + * IShellFolder2 interface + */ +/* IShellFolder2 */ + +/* GetDefaultColumnState */ +typedef enum +{ + SHCOLSTATE_TYPE_STR = 0x00000001, + SHCOLSTATE_TYPE_INT = 0x00000002, + SHCOLSTATE_TYPE_DATE = 0x00000003, + SHCOLSTATE_TYPEMASK = 0x0000000F, + SHCOLSTATE_ONBYDEFAULT = 0x00000010, + SHCOLSTATE_SLOW = 0x00000020, + SHCOLSTATE_EXTENDED = 0x00000040, + SHCOLSTATE_SECONDARYUI = 0x00000080, + SHCOLSTATE_HIDDEN = 0x00000100, +} SHCOLSTATE; + +typedef struct +{ + GUID fmtid; + DWORD pid; +} SHCOLUMNID, *LPSHCOLUMNID; +typedef const SHCOLUMNID* LPCSHCOLUMNID; + +/* GetDetailsEx */ +#define PID_FINDDATA 0 +#define PID_NETRESOURCE 1 +#define PID_DESCRIPTIONID 2 + +typedef struct +{ + int fmt; + int cxChar; + STRRET str; +} SHELLDETAILS, *LPSHELLDETAILS; + +#define ICOM_INTERFACE IShellFolder2 +#define IShellFolder2_METHODS \ + ICOM_METHOD1( HRESULT, GetDefaultSearchGUID, LPGUID, lpguid)\ + ICOM_METHOD1( HRESULT, EnumSearches, LPENUMEXTRASEARCH *, ppEnum) \ + ICOM_METHOD3( HRESULT, GetDefaultColumn, DWORD, dwReserved, ULONG *, pSort, ULONG *, pDisplay)\ + ICOM_METHOD2( HRESULT, GetDefaultColumnState, UINT, iColumn, DWORD *, pcsFlags)\ + ICOM_METHOD3( HRESULT, GetDetailsEx, LPCITEMIDLIST, pidl, const SHCOLUMNID *, pscid, VARIANT *, pv)\ + ICOM_METHOD3( HRESULT, GetDetailsOf, LPCITEMIDLIST, pidl, UINT, iColumn, LPSHELLDETAILS, pDetails)\ + ICOM_METHOD2( HRESULT, MapNameToSCID, LPCWSTR, pwszName, SHCOLUMNID *, pscid) +#define IShellFolder2_IMETHODS \ + IShellFolder_METHODS \ + IShellFolder2_METHODS +ICOM_DEFINE(IShellFolder2, IShellFolder) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IShellFolder2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IShellFolder2_AddRef(p) ICOM_CALL (AddRef,p) +#define IShellFolder2_Release(p) ICOM_CALL (Release,p) +/*** IShellFolder methods ***/ +#define IShellFolder2_ParseDisplayName(p,a,b,c,d,e,f) ICOM_CALL6(ParseDisplayName,p,a,b,c,d,e,f) +#define IShellFolder2_EnumObjects(p,a,b,c) ICOM_CALL3(EnumObjects,p,a,b,c) +#define IShellFolder2_BindToObject(p,a,b,c,d) ICOM_CALL4(BindToObject,p,a,b,c,d) +#define IShellFolder2_BindToStorage(p,a,b,c,d) ICOM_CALL4(BindToStorage,p,a,b,c,d) +#define IShellFolder2_CompareIDs(p,a,b,c) ICOM_CALL3(CompareIDs,p,a,b,c) +#define IShellFolder2_CreateViewObject(p,a,b,c) ICOM_CALL3(CreateViewObject,p,a,b,c) +#define IShellFolder2_GetAttributesOf(p,a,b,c) ICOM_CALL3(GetAttributesOf,p,a,b,c) +#define IShellFolder2_GetUIObjectOf(p,a,b,c,d,e,f) ICOM_CALL6(GetUIObjectOf,p,a,b,c,d,e,f) +#define IShellFolder2_GetDisplayNameOf(p,a,b,c) ICOM_CALL3(GetDisplayNameOf,p,a,b,c) +#define IShellFolder2_SetNameOf(p,a,b,c,d,e) ICOM_CALL5(SetNameOf,p,a,b,c,d,e) +/*** IShellFolder2 methods ***/ +#define IShellFolder2_GetDefaultSearchGUID(p,a) ICOM_CALL1(GetDefaultSearchGUID,p,a) +#define IShellFolder2_EnumSearches(p,a) ICOM_CALL1(EnumSearches,p,a) +#define IShellFolder2_GetDefaultColumn(p,a,b,c) ICOM_CALL3(GetDefaultColumn,p,a,b,c) +#define IShellFolder2_GetDefaultColumnState(p,a,b) ICOM_CALL2(GetDefaultColumnState,p,a,b) +#define IShellFolder2_GetDetailsEx(p,a,b,c) ICOM_CALL3(GetDetailsEx,p,a,b,c) +#define IShellFolder2_GetDetailsOf(p,a,b,c) ICOM_CALL3(GetDetailsOf,p,a,b,c) +#define IShellFolder2_MapNameToSCID(p,a,b) ICOM_CALL2(MapNameToSCID,p,a,b) + +/***************************************************************************** + * IPersistFolder interface + */ + +/* ClassID's */ +DEFINE_GUID (CLSID_SFMyComp,0x20D04FE0,0x3AEA,0x1069,0xA2,0xD8,0x08,0x00,0x2B,0x30,0x30,0x9D); +DEFINE_GUID (CLSID_SFINet, 0x871C5380,0x42A0,0x1069,0xA2,0xEA,0x08,0x00,0x2B,0x30,0x30,0x9D); +DEFINE_GUID (CLSID_SFFile, 0xF3364BA0,0x65B9,0x11CE,0xA9,0xBA,0x00,0xAA,0x00,0x4A,0xE8,0x37); + +#define ICOM_INTERFACE IPersistFolder +#define IPersistFolder_METHODS \ + ICOM_METHOD1( HRESULT, Initialize, LPCITEMIDLIST, pidl) +#define IPersistFolder_IMETHODS \ + IPersist_IMETHODS \ + IPersistFolder_METHODS +ICOM_DEFINE(IPersistFolder, IPersist) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPersistFolder_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPersistFolder_AddRef(p) ICOM_CALL (AddRef,p) +#define IPersistFolder_Release(p) ICOM_CALL (Release,p) +/*** IPersist methods ***/ +#define IPersistFolder_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) +/*** IPersistFolder methods ***/ +#define IPersistFolder_Initialize(p,a) ICOM_CALL1(Initialize,p,a) + +/***************************************************************************** + * IPersistFolder2 interface + */ + +#define ICOM_INTERFACE IPersistFolder2 +#define IPersistFolder2_METHODS \ + ICOM_METHOD1( HRESULT, GetCurFolder, LPITEMIDLIST*, pidl) +#define IPersistFolder2_IMETHODS \ + IPersist_IMETHODS \ + IPersistFolder_METHODS \ + IPersistFolder2_METHODS +ICOM_DEFINE(IPersistFolder2, IPersistFolder) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPersistFolder2_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPersistFolder2_AddRef(p) ICOM_CALL (AddRef,p) +#define IPersistFolder2_Release(p) ICOM_CALL (Release,p) +/*** IPersist methods ***/ +#define IPersistFolder2_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) +/*** IPersistFolder methods ***/ +#define IPersistFolder2_Initialize(p,a) ICOM_CALL1(Initialize,p,a) +/*** IPersistFolder2 methods ***/ +#define IPersistFolder2_GetCurFolder(p,a) ICOM_CALL1(GetCurFolder,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_SHELLFOLDER_H */ diff --git a/reactos/include/ole32/obj_shelllink.h b/reactos/include/ole32/obj_shelllink.h new file mode 100644 index 00000000000..79bf29f3344 --- /dev/null +++ b/reactos/include/ole32/obj_shelllink.h @@ -0,0 +1,146 @@ +/* + * Defines the COM interfaces and APIs related to IShellLink. + * + * Depends on 'obj_base.h'. + */ + +#ifndef __WINE_WINE_OBJ_SHELLLINK_H +#define __WINE_WINE_OBJ_SHELLLINK_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the interfaces + */ +typedef struct IShellLinkA IShellLinkA,*LPSHELLLINK; +typedef struct IShellLinkW IShellLinkW,*LPSHELLLINKW; + +/***************************************************************************** + * + */ +typedef enum +{ SLR_NO_UI = 0x0001, + SLR_ANY_MATCH = 0x0002, + SLR_UPDATE = 0x0004 +} SLR_FLAGS; + +/***************************************************************************** + * GetPath fFlags + */ +typedef enum +{ SLGP_SHORTPATH = 0x0001, + SLGP_UNCPRIORITY = 0x0002 +} SLGP_FLAGS; +/***************************************************************************** + * IShellLink interface + */ +#define ICOM_INTERFACE IShellLinkA +#define IShellLinkA_METHODS \ + ICOM_METHOD4( HRESULT, GetPath, LPSTR, pszFile, INT, cchMaxPath, WIN32_FIND_DATAA *, pfd, DWORD, fFlags) \ + ICOM_METHOD1( HRESULT, GetIDList, LPITEMIDLIST *, ppidl) \ + ICOM_METHOD1( HRESULT, SetIDList, LPCITEMIDLIST, pidl) \ + ICOM_METHOD2( HRESULT, GetDescription, LPSTR, pszName, INT, cchMaxName) \ + ICOM_METHOD1( HRESULT, SetDescription, LPCSTR, pszName) \ + ICOM_METHOD2( HRESULT, GetWorkingDirectory, LPSTR, pszDir,INT, cchMaxPath) \ + ICOM_METHOD1( HRESULT, SetWorkingDirectory, LPCSTR, pszDir) \ + ICOM_METHOD2( HRESULT, GetArguments, LPSTR, pszArgs, INT, cchMaxPath) \ + ICOM_METHOD1( HRESULT, SetArguments, LPCSTR, pszArgs) \ + ICOM_METHOD1( HRESULT, GetHotkey, WORD*, pwHotkey) \ + ICOM_METHOD1( HRESULT, SetHotkey, WORD, wHotkey) \ + ICOM_METHOD1( HRESULT, GetShowCmd, INT*, piShowCmd) \ + ICOM_METHOD1( HRESULT, SetShowCmd, INT, iShowCmd) \ + ICOM_METHOD3( HRESULT, GetIconLocation, LPSTR, pszIconPath, INT, cchIconPath,INT *, piIcon) \ + ICOM_METHOD2( HRESULT, SetIconLocation, LPCSTR, pszIconPath,INT, iIcon) \ + ICOM_METHOD2( HRESULT, SetRelativePath, LPCSTR, pszPathRel, DWORD, dwReserved) \ + ICOM_METHOD2( HRESULT, Resolve, HWND, hwnd, DWORD, fFlags) \ + ICOM_METHOD1( HRESULT, SetPath, LPCSTR, pszFile) +#define IShellLinkA_IMETHODS \ + IUnknown_IMETHODS \ + IShellLinkA_METHODS +ICOM_DEFINE(IShellLinkA,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IShellLinkA_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IShellLinkA_AddRef(p) ICOM_CALL (AddRef,p) +#define IShellLinkA_Release(p) ICOM_CALL (Release,p) +/*** IShellLink methods ***/ +#define IShellLinkA_GetPath(p,a,b,c,d) ICOM_CALL4(GetPath,p,a,b,c,d) +#define IShellLinkA_GetIDList(p,a) ICOM_CALL1(GetIDList,p,a) +#define IShellLinkA_SetIDList(p,a) ICOM_CALL1(SetIDList,p,a) +#define IShellLinkA_GetDescription(p,a,b) ICOM_CALL2(GetDescription,p,a,b) +#define IShellLinkA_SetDescription(p,a) ICOM_CALL1(SetDescription,p,a) +#define IShellLinkA_GetWorkingDirectory(p,a,b) ICOM_CALL2(GetWorkingDirectory,p,a,b) +#define IShellLinkA_SetWorkingDirectory(p,a) ICOM_CALL1(SetWorkingDirectory,p,a) +#define IShellLinkA_GetArguments(p,a,b) ICOM_CALL2(GetArguments,p,a,b) +#define IShellLinkA_SetArguments(p,a) ICOM_CALL1(SetArguments,p,a) +#define IShellLinkA_GetHotkey(p,a) ICOM_CALL1(GetHotkey,p,a) +#define IShellLinkA_SetHotkey(p,a) ICOM_CALL1(SetHotkey,p,a) +#define IShellLinkA_GetShowCmd(p,a) ICOM_CALL1(GetShowCmd,p,a) +#define IShellLinkA_SetShowCmd(p,a) ICOM_CALL1(SetShowCmd,p,a) +#define IShellLinkA_GetIconLocation(p,a,b,c) ICOM_CALL3(GetIconLocation,p,a,b,c) +#define IShellLinkA_SetIconLocation(p,a,b) ICOM_CALL2(SetIconLocation,p,a,b) +#define IShellLinkA_SetRelativePath(p,a,b) ICOM_CALL2(SetRelativePath,p,a,b) +#define IShellLinkA_Resolve(p,a,b) ICOM_CALL2(Resolve,p,a,b) +#define IShellLinkA_SetPath(p,a) ICOM_CALL1(SetPath,p,a) + +/***************************************************************************** + * IShellLinkW interface + */ +#define ICOM_INTERFACE IShellLinkW +#define IShellLinkW_METHODS \ + ICOM_METHOD4( HRESULT, GetPath, LPWSTR, pszFile, INT, cchMaxPath, WIN32_FIND_DATAA *, pfd, DWORD, fFlags) \ + ICOM_METHOD1( HRESULT, GetIDList, LPITEMIDLIST *, ppidl) \ + ICOM_METHOD1( HRESULT, SetIDList, LPCITEMIDLIST, pidl) \ + ICOM_METHOD2( HRESULT, GetDescription, LPWSTR, pszName, INT, cchMaxName) \ + ICOM_METHOD1( HRESULT, SetDescription, LPCWSTR, pszName) \ + ICOM_METHOD2( HRESULT, GetWorkingDirectory, LPWSTR, pszDir,INT, cchMaxPath) \ + ICOM_METHOD1( HRESULT, SetWorkingDirectory, LPCWSTR, pszDir) \ + ICOM_METHOD2( HRESULT, GetArguments, LPWSTR, pszArgs, INT, cchMaxPath) \ + ICOM_METHOD1( HRESULT, SetArguments, LPCWSTR, pszArgs) \ + ICOM_METHOD1( HRESULT, GetHotkey, WORD*, pwHotkey) \ + ICOM_METHOD1( HRESULT, SetHotkey, WORD, wHotkey) \ + ICOM_METHOD1( HRESULT, GetShowCmd, INT*, piShowCmd) \ + ICOM_METHOD1( HRESULT, SetShowCmd, INT, iShowCmd) \ + ICOM_METHOD3( HRESULT, GetIconLocation, LPWSTR, pszIconPath, INT, cchIconPath,INT *, piIcon) \ + ICOM_METHOD2( HRESULT, SetIconLocation, LPCWSTR, pszIconPath,INT, iIcon) \ + ICOM_METHOD2( HRESULT, SetRelativePath, LPCWSTR, pszPathRel, DWORD, dwReserved) \ + ICOM_METHOD2( HRESULT, Resolve, HWND, hwnd, DWORD, fFlags) \ + ICOM_METHOD1( HRESULT, SetPath, LPCWSTR, pszFile) +#define IShellLinkW_IMETHODS \ + IUnknown_IMETHODS \ + IShellLinkW_METHODS +ICOM_DEFINE(IShellLinkW,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IShellLinkW_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IShellLinkW_AddRef(p) ICOM_CALL (AddRef,p) +#define IShellLinkW_Release(p) ICOM_CALL (Release,p) +/*** IShellLinkW methods ***/ +#define IShellLinkW_GetPath(p,a,b,c,d) ICOM_CALL4(GetPath,p,a,b,c,d) +#define IShellLinkW_GetIDList(p,a) ICOM_CALL1(GetIDList,p,a) +#define IShellLinkW_SetIDList(p,a) ICOM_CALL1(SetIDList,p,a) +#define IShellLinkW_GetDescription(p,a,b) ICOM_CALL2(GetDescription,p,a,b) +#define IShellLinkW_SetDescription(p,a) ICOM_CALL1(SetDescription,p,a) +#define IShellLinkW_GetWorkingDirectory(p,a,b) ICOM_CALL2(GetWorkingDirectory,p,a,b) +#define IShellLinkW_SetWorkingDirectory(p,a) ICOM_CALL1(SetWorkingDirectory,p,a) +#define IShellLinkW_GetArguments(p,a,b) ICOM_CALL2(GetArguments,p,a,b) +#define IShellLinkW_SetArguments(p,a) ICOM_CALL1(SetArguments,p,a) +#define IShellLinkW_GetHotkey(p,a) ICOM_CALL1(GetHotkey,p,a) +#define IShellLinkW_SetHotkey(p,a) ICOM_CALL1(SetHotkey,p,a) +#define IShellLinkW_GetShowCmd(p,a) ICOM_CALL1(GetShowCmd,p,a) +#define IShellLinkW_SetShowCmd(p,a) ICOM_CALL1(SetShowCmd,p,a) +#define IShellLinkW_GetIconLocation(p,a,b,c) ICOM_CALL3(GetIconLocation,p,a,b,c) +#define IShellLinkW_SetIconLocation(p,a,b) ICOM_CALL2(SetIconLocation,p,a,b) +#define IShellLinkW_SetRelativePath(p,a,b) ICOM_CALL2(SetRelativePath,p,a,b) +#define IShellLinkW_Resolve(p,a,b) ICOM_CALL2(Resolve,p,a,b) +#define IShellLinkW_SetPath(p,a) ICOM_CALL1(SetPath,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_SHELLLINK_H */ diff --git a/reactos/include/ole32/obj_shellview.h b/reactos/include/ole32/obj_shellview.h new file mode 100644 index 00000000000..5786bcc7882 --- /dev/null +++ b/reactos/include/ole32/obj_shellview.h @@ -0,0 +1,159 @@ +/************************************************************ + * IShellView + */ + +#ifndef __WINE_WINE_OBJ_SHELLVIEW_H +#define __WINE_WINE_OBJ_SHELLVIEW_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/**************************************************************************** + * IShellBrowser is here defined because of a cyclic dependance between + * IShellBrowser and IShellView + */ +typedef struct IShellBrowser IShellBrowser, *LPSHELLBROWSER; + +typedef struct IShellView IShellView, *LPSHELLVIEW; + +/* shellview select item flags*/ +#define SVSI_DESELECT 0x0000 +#define SVSI_SELECT 0x0001 +#define SVSI_EDIT 0x0003 /* includes select */ +#define SVSI_DESELECTOTHERS 0x0004 +#define SVSI_ENSUREVISIBLE 0x0008 +#define SVSI_FOCUSED 0x0010 + +/* shellview get item object flags */ +#define SVGIO_BACKGROUND 0x00000000 +#define SVGIO_SELECTION 0x00000001 +#define SVGIO_ALLVIEW 0x00000002 + +/* The explorer dispatches WM_COMMAND messages based on the range of + command/menuitem IDs. All the IDs of menuitems that the view (right + pane) inserts must be in FCIDM_SHVIEWFIRST/LAST (otherwise, the explorer + won't dispatch them). The view should not deal with any menuitems + in FCIDM_BROWSERFIRST/LAST (otherwise, it won't work with the future + version of the shell). + + FCIDM_SHVIEWFIRST/LAST for the right pane (IShellView) + FCIDM_BROWSERFIRST/LAST for the explorer frame (IShellBrowser) + FCIDM_GLOBAL/LAST for the explorer's submenu IDs +*/ +#define FCIDM_SHVIEWFIRST 0x0000 +/* undocumented */ +#define FCIDM_SHVIEW_ARRANGE 0x7001 +#define FCIDM_SHVIEW_DELETE 0x7011 +#define FCIDM_SHVIEW_PROPERTIES 0x7013 +#define FCIDM_SHVIEW_CUT 0x7018 +#define FCIDM_SHVIEW_COPY 0x7019 +#define FCIDM_SHVIEW_INSERT 0x701A +#define FCIDM_SHVIEW_UNDO 0x701B +#define FCIDM_SHVIEW_INSERTLINK 0x701C +#define FCIDM_SHVIEW_SELECTALL 0x7021 +#define FCIDM_SHVIEW_INVERTSELECTION 0x7022 + +#define FCIDM_SHVIEW_BIGICON 0x7029 +#define FCIDM_SHVIEW_SMALLICON 0x702A +#define FCIDM_SHVIEW_LISTVIEW 0x702B +#define FCIDM_SHVIEW_REPORTVIEW 0x702C +/* 0x7030-0x703f are used by the shellbrowser */ +#define FCIDM_SHVIEW_AUTOARRANGE 0x7031 +#define FCIDM_SHVIEW_SNAPTOGRID 0x7032 + +#define FCIDM_SHVIEW_HELP 0x7041 +#define FCIDM_SHVIEW_RENAME 0x7050 +#define FCIDM_SHVIEW_CREATELINK 0x7051 +#define FCIDM_SHVIEW_NEWLINK 0x7052 +#define FCIDM_SHVIEW_NEWFOLDER 0x7053 + +#define FCIDM_SHVIEW_REFRESH 0x7100 /* fixme */ +#define FCIDM_SHVIEW_EXPLORE 0x7101 /* fixme */ +#define FCIDM_SHVIEW_OPEN 0x7102 /* fixme */ + +#define FCIDM_SHVIEWLAST 0x7fff +#define FCIDM_BROWSERFIRST 0xA000 +/* undocumented toolbar items from stddlg's*/ +#define FCIDM_TB_UPFOLDER 0xA001 +#define FCIDM_TB_NEWFOLDER 0xA002 +#define FCIDM_TB_SMALLICON 0xA003 +#define FCIDM_TB_REPORTVIEW 0xA004 +#define FCIDM_TB_DESKTOP 0xA005 /* fixme */ + +#define FCIDM_BROWSERLAST 0xbf00 +#define FCIDM_GLOBALFIRST 0x8000 +#define FCIDM_GLOBALLAST 0x9fff + +/* +* Global submenu IDs and separator IDs +*/ +#define FCIDM_MENU_FILE (FCIDM_GLOBALFIRST+0x0000) +#define FCIDM_MENU_EDIT (FCIDM_GLOBALFIRST+0x0040) +#define FCIDM_MENU_VIEW (FCIDM_GLOBALFIRST+0x0080) +#define FCIDM_MENU_VIEW_SEP_OPTIONS (FCIDM_GLOBALFIRST+0x0081) +#define FCIDM_MENU_TOOLS (FCIDM_GLOBALFIRST+0x00c0) +#define FCIDM_MENU_TOOLS_SEP_GOTO (FCIDM_GLOBALFIRST+0x00c1) +#define FCIDM_MENU_HELP (FCIDM_GLOBALFIRST+0x0100) +#define FCIDM_MENU_FIND (FCIDM_GLOBALFIRST+0x0140) +#define FCIDM_MENU_EXPLORE (FCIDM_GLOBALFIRST+0x0150) +#define FCIDM_MENU_FAVORITES (FCIDM_GLOBALFIRST+0x0170) + +/* control IDs known to the view */ +#define FCIDM_TOOLBAR (FCIDM_BROWSERFIRST + 0) +#define FCIDM_STATUS (FCIDM_BROWSERFIRST + 1) + +/* uState values for IShellView::UIActivate */ +typedef enum +{ SVUIA_DEACTIVATE = 0, + SVUIA_ACTIVATE_NOFOCUS = 1, + SVUIA_ACTIVATE_FOCUS = 2, + SVUIA_INPLACEACTIVATE = 3 /* new flag for IShellView2 */ +} SVUIA_STATUS; + +#define ICOM_INTERFACE IShellView +#define IShellView_METHODS \ + ICOM_METHOD1(HRESULT, TranslateAccelerator, LPMSG, lpmsg) \ + ICOM_METHOD1(HRESULT, EnableModeless, BOOL, fEnable) \ + ICOM_METHOD1(HRESULT, UIActivate, UINT, uState) \ + ICOM_METHOD(HRESULT, Refresh) \ + ICOM_METHOD5(HRESULT, CreateViewWindow, IShellView*, lpPrevView, LPCFOLDERSETTINGS, lpfs, IShellBrowser*, psb, RECT*, prcView, HWND*, phWnd) \ + ICOM_METHOD(HRESULT, DestroyViewWindow) \ + ICOM_METHOD1(HRESULT, GetCurrentInfo, LPFOLDERSETTINGS, lpfs) \ + ICOM_METHOD3(HRESULT, AddPropertySheetPages, DWORD, dwReserved, LPFNADDPROPSHEETPAGE, lpfn, LPARAM, lparam) \ + ICOM_METHOD (HRESULT, SaveViewState) \ + ICOM_METHOD2(HRESULT, SelectItem, LPCITEMIDLIST, pidlItem, UINT, uFlags) \ + ICOM_METHOD3(HRESULT, GetItemObject, UINT, uItem, REFIID, riid, LPVOID*, ppv) \ + ICOM_METHOD1(HRESULT, EditItem, LPCITEMIDLIST, pidlItem) +#define IShellView_IMETHODS \ + IOleWindow_IMETHODS \ + IShellView_METHODS +ICOM_DEFINE(IShellView,IOleWindow) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IShellView_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IShellView_AddRef(p) ICOM_CALL(AddRef,p) +#define IShellView_Release(p) ICOM_CALL(Release,p) +/*** IShellView methods ***/ +#define IShellView_GetWindow(p,a) ICOM_CALL1(GetWindow,p,a) +#define IShellView_ContextSensitiveHelp(p,a) ICOM_CALL1(ContextSensitiveHelp,p,a) +#define IShellView_TranslateAccelerator(p,a) ICOM_CALL1(TranslateAccelerator,p,a) +#define IShellView_EnableModeless(p,a) ICOM_CALL1(EnableModeless,p,a) +#define IShellView_UIActivate(p,a) ICOM_CALL1(UIActivate,p,a) +#define IShellView_Refresh(p) ICOM_CALL(Refresh,p) +#define IShellView_CreateViewWindow(p,a,b,c,d,e) ICOM_CALL5(CreateViewWindow,p,a,b,c,d,e) +#define IShellView_DestroyViewWindow(p) ICOM_CALL(DestroyViewWindow,p) +#define IShellView_GetCurrentInfo(p,a) ICOM_CALL1(GetCurrentInfo,p,a) +#define IShellView_AddPropertySheetPages(p,a,b,c) ICOM_CALL3(AddPropertySheetPages,p,a,b,c) +#define IShellView_SaveViewState(p) ICOM_CALL(SaveViewState,p) +#define IShellView_SelectItem(p,a,b) ICOM_CALL2(SelectItem,p,a,b) +#define IShellView_GetItemObject(p,a,b,c) ICOM_CALL3(GetItemObject,p,a,b,c) +/* WINE specific */ +#define IShellView_EditItem(p,a) ICOM_CALL1(EditItem,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_SHELLVIEW_H */ diff --git a/reactos/include/ole32/obj_storage.h b/reactos/include/ole32/obj_storage.h new file mode 100644 index 00000000000..2449d79a895 --- /dev/null +++ b/reactos/include/ole32/obj_storage.h @@ -0,0 +1,650 @@ +/* + * Defines the COM interfaces and APIs related to structured data storage. + */ + +#ifndef __WINE_WINE_OBJ_STORAGE_H +#define __WINE_WINE_OBJ_STORAGE_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/***************************************************************************** + * Predeclare the structures + */ +typedef enum tagLOCKTYPE +{ + LOCK_WRITE = 1, + LOCK_EXCLUSIVE = 2, + LOCK_ONLYONCE = 4 +} LOCKTYPE; + +typedef struct tagStorageLayout +{ + DWORD LayoutType; + OLECHAR16* pwcsElementName; + LARGE_INTEGER cOffset; + LARGE_INTEGER cBytes; +} StorageLayout; + +typedef struct tagSTATSTG { + LPOLESTR pwcsName; + DWORD type; + ULARGE_INTEGER cbSize; + FILETIME mtime; + FILETIME ctime; + FILETIME atime; + DWORD grfMode; + DWORD grfLocksSupported; + CLSID clsid; + DWORD grfStateBits; + DWORD reserved; +} STATSTG; + +typedef struct tagSTATSTG16 { + LPOLESTR16 pwcsName; + DWORD type; + ULARGE_INTEGER cbSize; + FILETIME mtime; + FILETIME ctime; + FILETIME atime; + DWORD grfMode; + DWORD grfLocksSupported; + CLSID clsid; + DWORD grfStateBits; + DWORD reserved; +} STATSTG16; + +typedef LPOLESTR16 *SNB16; +typedef LPOLESTR *SNB; + + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_OLEGUID(IID_IEnumSTATSTG, 0x0000000dL, 0, 0); +typedef struct IEnumSTATSTG IEnumSTATSTG,*LPENUMSTATSTG; + +DEFINE_GUID (IID_IFillLockBytes, 0x99caf010L, 0x415e, 0x11cf, 0x88, 0x14, 0x00, 0xaa, 0x00, 0xb5, 0x69, 0xf5); +typedef struct IFillLockBytes IFillLockBytes,*LPFILLLOCKBYTES; + +DEFINE_GUID (IID_ILayoutStorage, 0x0e6d4d90L, 0x6738, 0x11cf, 0x96, 0x08, 0x00, 0xaa, 0x00, 0x68, 0x0d, 0xb4); +typedef struct ILayoutStorage ILayoutStorage,*LPLAYOUTSTORAGE; + +DEFINE_OLEGUID(IID_ILockBytes, 0x0000000aL, 0, 0); +typedef struct ILockBytes ILockBytes,*LPLOCKBYTES; + +DEFINE_OLEGUID(IID_IPersist, 0x0000010cL, 0, 0); +typedef struct IPersist IPersist,*LPPERSIST; + +DEFINE_OLEGUID(IID_IPersistFile, 0x0000010bL, 0, 0); +typedef struct IPersistFile IPersistFile,*LPPERSISTFILE; + +DEFINE_OLEGUID(IID_IPersistStorage, 0x0000010aL, 0, 0); +typedef struct IPersistStorage IPersistStorage,*LPPERSISTSTORAGE; + +DEFINE_OLEGUID(IID_IPersistStream, 0x00000109L, 0, 0); +typedef struct IPersistStream IPersistStream,*LPPERSISTSTREAM; + +DEFINE_GUID (IID_IProgressNotify, 0xa9d758a0L, 0x4617, 0x11cf, 0x95, 0xfc, 0x00, 0xaa, 0x00, 0x68, 0x0d, 0xb4); +typedef struct IProgressNotify IProgressNotify,*LPPROGRESSNOTIFY; + +DEFINE_OLEGUID(IID_IRootStorage, 0x00000012L, 0, 0); +typedef struct IRootStorage IRootStorage,*LPROOTSTORAGE; + +DEFINE_GUID (IID_ISequentialStream, 0x0c733a30L, 0x2a1c, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d); +typedef struct ISequentialStream ISequentialStream,*LPSEQUENTIALSTREAM; + +DEFINE_OLEGUID(IID_IStorage, 0x0000000bL, 0, 0); +typedef struct IStorage16 IStorage16,*LPSTORAGE16; +typedef struct IStorage IStorage,*LPSTORAGE; + +DEFINE_OLEGUID(IID_IStream, 0x0000000cL, 0, 0); +typedef struct IStream16 IStream16,*LPSTREAM16; +typedef struct IStream IStream,*LPSTREAM; + + +/***************************************************************************** + * STGM enumeration + * + * See IStorage and IStream + */ +#define STGM_DIRECT 0x00000000 +#define STGM_TRANSACTED 0x00010000 +#define STGM_SIMPLE 0x08000000 +#define STGM_READ 0x00000000 +#define STGM_WRITE 0x00000001 +#define STGM_READWRITE 0x00000002 +#define STGM_SHARE_DENY_NONE 0x00000040 +#define STGM_SHARE_DENY_READ 0x00000030 +#define STGM_SHARE_DENY_WRITE 0x00000020 +#define STGM_SHARE_EXCLUSIVE 0x00000010 +#define STGM_PRIORITY 0x00040000 +#define STGM_DELETEONRELEASE 0x04000000 +#define STGM_CREATE 0x00001000 +#define STGM_CONVERT 0x00020000 +#define STGM_FAILIFTHERE 0x00000000 +#define STGM_NOSCRATCH 0x00100000 +#define STGM_NOSNAPSHOT 0x00200000 + +/***************************************************************************** + * STGTY enumeration + * + * See IStorage + */ +#define STGTY_STORAGE 1 +#define STGTY_STREAM 2 +#define STGTY_LOCKBYTES 3 +#define STGTY_PROPERTY 4 + +/***************************************************************************** + * STATFLAG enumeration + * + * See IStorage and IStream + */ +#define STATFLAG_DEFAULT 0 +#define STATFLAG_NONAME 1 + +/***************************************************************************** + * STREAM_SEEK enumeration + * + * See IStream + */ +#define STREAM_SEEK_SET 0 +#define STREAM_SEEK_CUR 1 +#define STREAM_SEEK_END 2 + +/***************************************************************************** + * IEnumSTATSTG interface + */ +#define ICOM_INTERFACE IEnumSTATSTG +#define IEnumSTATSTG_METHODS \ + ICOM_METHOD3(HRESULT,Next, ULONG,celt, STATSTG*,rgelt, ULONG*,pceltFethed) \ + ICOM_METHOD1(HRESULT,Skip, ULONG,celt) \ + ICOM_METHOD (HRESULT,Reset) \ + ICOM_METHOD1(HRESULT,Clone, IEnumSTATSTG**,ppenum) +#define IEnumSTATSTG_IMETHODS \ + IUnknown_IMETHODS \ + IEnumSTATSTG_METHODS +ICOM_DEFINE(IEnumSTATSTG,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IEnumSTATSTG_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IEnumSTATSTG_AddRef(p) ICOM_CALL (AddRef,p) +#define IEnumSTATSTG_Release(p) ICOM_CALL (Release,p) +/*** IEnumSTATSTG methods ***/ +#define IEnumSTATSTG_Next(p,a,b,c) ICOM_CALL3(Next,p,a,b,c) +#define IEnumSTATSTG_Skip(p,a) ICOM_CALL1(Skip,p,a) +#define IEnumSTATSTG_Reset(p) ICOM_CALL(Reset,p) +#define IEnumSTATSTG_Clone(p,a) ICOM_CALL1(Clone,p,a) + + +/***************************************************************************** + * IFillLockBytes interface + */ +#define ICOM_INTERFACE IFillLockBytes +#define IFillLockBytes_METHODS \ + ICOM_METHOD3(HRESULT,FillAppend, const void*,pv, ULONG,cb, ULONG*,pcbWritten) \ + ICOM_METHOD4(HRESULT,FillAt, ULARGE_INTEGER,ulOffset, const void*,pv, ULONG,cb, ULONG*,pcbWritten) \ + ICOM_METHOD1(HRESULT,SetFillSize, ULARGE_INTEGER,ulSize) \ + ICOM_METHOD1(HRESULT,Terminate, BOOL,bCanceled) +#define IFillLockBytes_IMETHODS \ + IUnknown_IMETHODS \ + IFillLockBytes_METHODS +ICOM_DEFINE(IFillLockBytes,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IFillLockBytes_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IFillLockBytes_AddRef(p) ICOM_CALL (AddRef,p) +#define IFillLockBytes_Release(p) ICOM_CALL (Release,p) +/*** IFillLockBytes methods ***/ +#define IFillLockBytes_FillAppend(p,a,b,c) ICOM_CALL3(FillAppend,p,a,b,c) +#define IFillLockBytes_FillAt(p,a,b,c,d) ICOM_CALL4(FillAt,p,a,b,c,d) +#define IFillLockBytes_SetFillSize(p,a) ICOM_CALL1(SetFillSize,p,a) +#define IFillLockBytes_Terminate(p,a) ICOM_CALL1(Terminate,p,a) + + +/***************************************************************************** + * ILayoutStorage interface + */ +#define ICOM_INTERFACE ILayoutStorage +#define ILayoutStorage_METHODS \ + ICOM_METHOD2(HRESULT,LayoutScript, DWORD,nEntries, DWORD,glfInterleavedFlag) \ + ICOM_METHOD (HRESULT,BeginMonitor) \ + ICOM_METHOD (HRESULT,EndMonitor) \ + ICOM_METHOD1(HRESULT,ReLayoutDocfile, OLECHAR16*,pwcsNewDfName) \ + ICOM_METHOD1(HRESULT,ReLayoutDocfileOnILockBytes, ILockBytes*,pILockBytes) +#define ILayoutStorage_IMETHODS \ + IUnknown_IMETHODS \ + ILayoutStorage_METHODS +ICOM_DEFINE(ILayoutStorage,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ILayoutStorage_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ILayoutStorage_AddRef(p) ICOM_CALL (AddRef,p) +#define ILayoutStorage_Release(p) ICOM_CALL (Release,p) +/*** ILayoutStorage methods ***/ +#define ILayoutStorage_LayoutScript(p,a,b) ICOM_CALL2(LayoutScript,p,a,b) +#define ILayoutStorage_BeginMonitor(p) ICOM_CALL (BeginMonitor,p) +#define ILayoutStorage_EndMonitor(p) ICOM_CALL (EndMonitor,p) +#define ILayoutStorage_ReLayoutDocfile(p,a) ICOM_CALL1(ReLayoutDocfile,p,a) +#define ILayoutStorage_ReLayoutDocfileOnILockBytes(p,a) ICOM_CALL1(ReLayoutDocfileOnILockBytes,p,a) + + +/***************************************************************************** + * ILockBytes interface + */ +#define ICOM_INTERFACE ILockBytes +#define ILockBytes_METHODS \ + ICOM_METHOD4(HRESULT,ReadAt, ULARGE_INTEGER,ulOffset, void*,pv, ULONG,cb, ULONG*,pcbRead) \ + ICOM_METHOD4(HRESULT,WriteAt, ULARGE_INTEGER,ulOffset, const void*,pv, ULONG,cb, ULONG*,pcbWritten) \ + ICOM_METHOD (HRESULT,Flush) \ + ICOM_METHOD1(HRESULT,SetSize, ULARGE_INTEGER,cb) \ + ICOM_METHOD3(HRESULT,LockRegion, ULARGE_INTEGER,libOffset, ULARGE_INTEGER,cb, DWORD,dwLockType) \ + ICOM_METHOD3(HRESULT,UnlockRegion, ULARGE_INTEGER,libOffset, ULARGE_INTEGER,cb, DWORD,dwLockType) \ + ICOM_METHOD2(HRESULT,Stat, STATSTG*,pstatstg, DWORD,grfStatFlag) +#define ILockBytes_IMETHODS \ + IUnknown_IMETHODS \ + ILockBytes_METHODS +ICOM_DEFINE(ILockBytes,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ILockBytes_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ILockBytes_AddRef(p) ICOM_CALL (AddRef,p) +#define ILockBytes_Release(p) ICOM_CALL (Release,p) +/*** ILockBytes methods ***/ +#define ILockBytes_ReadAt(p,a,b,c,d) ICOM_CALL4(ReadAt,p,a,b,c,d) +#define ILockBytes_WriteAt(p,a,b,c,d) ICOM_CALL4(WriteAt,p,a,b,c,d) +#define ILockBytes_Flush(p) ICOM_CALL (Flush,p) +#define ILockBytes_SetSize(p,a) ICOM_CALL1(SetSize,p,a) +#define ILockBytes_LockRegion(p,a,b,c) ICOM_CALL3(LockRegion,p,a,b,c) +#define ILockBytes_UnlockRegion(p,a,b,c) ICOM_CALL3(UnlockRegion,p,a,b,c) +#define ILockBytes_Stat(p,a,b) ICOM_CALL2(Stat,p,a,b) + + +/***************************************************************************** + * IPersist interface + */ +#define ICOM_INTERFACE IPersist +#define IPersist_METHODS \ + ICOM_METHOD1(HRESULT,GetClassID, CLSID*,pClassID) +#define IPersist_IMETHODS \ + IUnknown_IMETHODS \ + IPersist_METHODS +ICOM_DEFINE(IPersist,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPersist_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPersist_AddRef(p) ICOM_CALL (AddRef,p) +#define IPersist_Release(p) ICOM_CALL (Release,p) +/*** IPersist methods ***/ +#define IPersist_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) + + +/***************************************************************************** + * IPersistFile interface + */ +#define ICOM_INTERFACE IPersistFile +#define IPersistFile_METHODS \ + ICOM_METHOD (HRESULT,IsDirty) \ + ICOM_METHOD2 (HRESULT,Load, LPCOLESTR,pszFileName, DWORD,dwMode) \ + ICOM_METHOD2 (HRESULT,Save, LPCOLESTR,pszFileName, BOOL,fRemember) \ + ICOM_METHOD1 (HRESULT,SaveCompleted, LPCOLESTR,pszFileName) \ + ICOM_METHOD1(HRESULT,GetCurFile, LPOLESTR*,ppszFileName) +#define IPersistFile_IMETHODS \ + IPersist_IMETHODS \ + IPersistFile_METHODS +ICOM_DEFINE(IPersistFile,IPersist) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPersistFile_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPersistFile_AddRef(p) ICOM_CALL (AddRef,p) +#define IPersistFile_Release(p) ICOM_CALL (Release,p) +/*** IPersist methods ***/ +#define IPersistFile_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) +/*** IPersistFile methods ***/ +#define IPersistFile_IsDirty(p) ICOM_CALL(IsDirty,p) +#define IPersistFile_Load(p,a,b) ICOM_CALL2(Load,p,a,b) +#define IPersistFile_Save(p,a,b) ICOM_CALL2(Save,p,a,b) +#define IPersistFile_SaveCompleted(p,a) ICOM_CALL1(SaveCompleted,p,a) +#define IPersistFile_GetCurFile(p,a) ICOM_CALL1(GetCurFile,p,a) + + +/***************************************************************************** + * IPersistStorage interface + */ +#define ICOM_INTERFACE IPersistStorage +#define IPersistStorage_METHODS \ + ICOM_METHOD (HRESULT,IsDirty) \ + ICOM_METHOD1(HRESULT,InitNew, IStorage*,pStg) \ + ICOM_METHOD1(HRESULT,Load, IStorage*,pStg) \ + ICOM_METHOD2(HRESULT,Save, IStorage*,pStg, BOOL,fSameAsLoad) \ + ICOM_METHOD1(HRESULT,SaveCompleted, IStorage*,pStgNew) \ + ICOM_METHOD (HRESULT,HandsOffStorage) +#define IPersistStorage_IMETHODS \ + IPersist_IMETHODS \ + IPersistStorage_METHODS +ICOM_DEFINE(IPersistStorage,IPersist) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPersistStorage_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPersistStorage_AddRef(p) ICOM_CALL (AddRef,p) +#define IPersistStorage_Release(p) ICOM_CALL (Release,p) +/*** IPersist methods ***/ +#define IPersistStorage_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) +/*** IPersistStorage methods ***/ +#define IPersistStorage_IsDirty(p) ICOM_CALL (IsDirty,p) +#define IPersistStorage_InitNew(p,a) ICOM_CALL1(InitNew,p,a) +#define IPersistStorage_Load(p,a) ICOM_CALL1(Load,p,a) +#define IPersistStorage_Save(p,a,b) ICOM_CALL2(Save,p,a,b) +#define IPersistStorage_SaveCompleted(p,a) ICOM_CALL1(SaveCompleted,p,a) +#define IPersistStorage_HandsOffStorage(p) ICOM_CALL (HandsOffStorage,p) + + +/***************************************************************************** + * IPersistStream interface + */ +#define ICOM_INTERFACE IPersistStream +#define IPersistStream_METHODS \ + ICOM_METHOD (HRESULT,IsDirty) \ + ICOM_METHOD1(HRESULT,Load, IStream*,pStm) \ + ICOM_METHOD2(HRESULT,Save, IStream*,pStm, BOOL,fClearDirty) \ + ICOM_METHOD1(HRESULT,GetSizeMax, ULARGE_INTEGER*,pcbSize) +#define IPersistStream_IMETHODS \ + IPersist_IMETHODS \ + IPersistStream_METHODS +ICOM_DEFINE(IPersistStream,IPersist) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IPersistStream_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IPersistStream_AddRef(p) ICOM_CALL (AddRef,p) +#define IPersistStream_Release(p) ICOM_CALL (Release,p) +/*** IPersist methods ***/ +#define IPersistStream_GetClassID(p,a) ICOM_CALL1(GetClassID,p,a) +/*** IPersistStream methods ***/ +#define IPersistStream_IsDirty(p) ICOM_CALL (IsDirty,p) +#define IPersistStream_Load(p,a) ICOM_CALL1(Load,p,a) +#define IPersistStream_Save(p,a,b) ICOM_CALL2(Save,p,a,b) +#define IPersistStream_GetSizeMax(p,a) ICOM_CALL1(GetSizeMax,p,a) + + +/***************************************************************************** + * IProgressNotify interface + */ +#define ICOM_INTERFACE IProgressNotify +#define IProgressNotify_METHODS \ + ICOM_METHOD4(HRESULT,OnProgress, DWORD,dwProgressCurrent, DWORD,dwProgressMaximum, BOOL,fAccurate, BOOL,fOwner) +#define IProgressNotify_IMETHODS \ + IUnknown_IMETHODS \ + IProgressNotify_METHODS +ICOM_DEFINE(IProgressNotify,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IProgressNotify_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IProgressNotify_AddRef(p) ICOM_CALL (AddRef,p) +#define IProgressNotify_Release(p) ICOM_CALL (Release,p) +/*** IProgressNotify methods ***/ +#define IProgressNotify_OnProgress(p,a,b,c,d) ICOM_CALL4(OnProgress,p,a,b,c,d) + + +/***************************************************************************** + * IRootStorage interface + */ +#define ICOM_INTERFACE IRootStorage +#define IRootStorage_METHODS \ + ICOM_METHOD1(HRESULT,SwitchToFile, LPOLESTR,pszFile) +#define IRootStorage_IMETHODS \ + IUnknown_IMETHODS \ + IRootStorage_METHODS +ICOM_DEFINE(IRootStorage,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IRootStorage_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IRootStorage_AddRef(p) ICOM_CALL (AddRef,p) +#define IRootStorage_Release(p) ICOM_CALL (Release,p) +/*** IRootStorage methods ***/ +#define IRootStorage_SwitchToFile(p,a) ICOM_CALLSwitchToFile(,p,a) + + +/***************************************************************************** + * ISequentialStream interface + */ +#define ICOM_INTERFACE ISequentialStream +#define ISequentialStream_METHODS \ + ICOM_METHOD3(HRESULT,Read, void*,pv, ULONG,cb, ULONG*,pcbRead) \ + ICOM_METHOD3(HRESULT,Write, const void*,pv, ULONG,cb, ULONG*,pcbWritten) +#define ISequentialStream_IMETHODS \ + IUnknown_IMETHODS \ + ISequentialStream_METHODS +ICOM_DEFINE(ISequentialStream,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define ISequentialStream_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define ISequentialStream_AddRef(p) ICOM_CALL (AddRef,p) +#define ISequentialStream_Release(p) ICOM_CALL (Release,p) +/*** ISequentialStream methods ***/ +#define ISequentialStream_Read(p,a,b,c) ICOM_CALL3(Read,p,a,b,c) +#define ISequentialStream_Write(p,a,b,c) ICOM_CALL3(Write,p,a,b,c) + + +/***************************************************************************** + * IStorage interface + */ +#define ICOM_INTERFACE IStorage16 +#define IStorage16_METHODS \ + ICOM_METHOD5(HRESULT,CreateStream, LPCOLESTR16,pwcsName, DWORD,grfMode, DWORD,reserved1, DWORD,reserved2, IStream16**,ppstm) \ + ICOM_METHOD5(HRESULT,OpenStream, LPCOLESTR16,pwcsName, void*,reserved1, DWORD,grfMode, DWORD,reserved2, IStream16**,ppstm) \ + ICOM_METHOD5(HRESULT,CreateStorage, LPCOLESTR16,pwcsName, DWORD,grfMode, DWORD,dwStgFmt, DWORD,reserved2, IStorage16**,ppstg) \ + ICOM_METHOD6(HRESULT,OpenStorage, LPCOLESTR16,pwcsName, IStorage16*,pstgPriority, DWORD,grfMode, SNB16,snb16Exclude, DWORD,reserved, IStorage16**,ppstg) \ + ICOM_METHOD4(HRESULT,CopyTo, DWORD,ciidExclude, const IID*,rgiidExclude, SNB16,snb16Exclude, IStorage16*,pstgDest) \ + ICOM_METHOD4(HRESULT,MoveElementTo, LPCOLESTR16,pwcsName, IStorage16*,pstgDest, LPCOLESTR16,pwcsNewName, DWORD,grfFlags) \ + ICOM_METHOD1(HRESULT,Commit, DWORD,grfCommitFlags) \ + ICOM_METHOD (HRESULT,Revert) \ + ICOM_METHOD4(HRESULT,EnumElements, DWORD,reserved1, void*,reserved2, DWORD,reserved3, IEnumSTATSTG**,ppenum) \ + ICOM_METHOD1(HRESULT,DestroyElement, LPCOLESTR16,pwcsName) \ + ICOM_METHOD2(HRESULT,RenameElement, LPCOLESTR16,pwcsOldName, LPOLESTR16,pwcsNewName) \ + ICOM_METHOD4(HRESULT,SetElementTimes,LPCOLESTR16,pwcsName, const FILETIME*,pctime, const FILETIME*,patime, const FILETIME*,pmtime) \ + ICOM_METHOD1(HRESULT,SetClass, REFCLSID,clsid) \ + ICOM_METHOD2(HRESULT,SetStateBits, DWORD,grfStateBits, DWORD,grfMask) \ + ICOM_METHOD2(HRESULT,Stat, STATSTG*,pstatstg, DWORD,grfStatFlag) +#define IStorage16_IMETHODS \ + IUnknown_IMETHODS \ + IStorage16_METHODS +ICOM_DEFINE(IStorage16,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IStorage16_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IStorage16_AddRef(p) ICOM_CALL (AddRef,p) +#define IStorage16_Release(p) ICOM_CALL (Release,p) +/*** IStorage16 methods ***/ +#define IStorage16_CreateStream(p,a,b,c,d,e) ICOM_CALL5(CreateStream,p,a,b,c,d,e) +#define IStorage16_OpenStream(p,a,b,c,d,e) ICOM_CALL5(OpenStream,p,a,b,c,d,e) +#define IStorage16_CreateStorage(p,a,b,c,d,e) ICOM_CALL5(CreateStorage,p,a,b,c,d,e) +#define IStorage16_OpenStorage(p,a,b,c,d,e,f) ICOM_CALL6(OpenStorage,p,a,b,c,d,e,f) +#define IStorage16_CopyTo(p,a,b,c,d) ICOM_CALL4(CopyTo,p,a,b,c,d) +#define IStorage16_MoveElementTo(p,a,b,c,d) ICOM_CALL4(MoveElementTo,p,a,b,c,d) +#define IStorage16_Commit(p,a) ICOM_CALL1(Commit,p,a) +#define IStorage16_Revert(p) ICOM_CALL (Revert,p) +#define IStorage16_EnumElements(p,a,b,c,d) ICOM_CALL4(EnumElements,p,a,b,c,d) +#define IStorage16_DestroyElement(p,a) ICOM_CALL1(DestroyElement,p,a) +#define IStorage16_RenameElement(p,a,b) ICOM_CALL2(RenameElement,p,a,b) +#define IStorage16_SetElementTimes(p,a,b,c,d) ICOM_CALL4(SetElementTimes,p,a,b,c,d) +#define IStorage16_SetClass(p,a) ICOM_CALL1(SetClass,p,a) +#define IStorage16_SetStateBits(p,a,b) ICOM_CALL2(SetStateBits,p,a,b) +#define IStorage16_Stat(p,a,b) ICOM_CALL2(Stat,p,a,b) + + +#define ICOM_INTERFACE IStorage +#define IStorage_METHODS \ + ICOM_METHOD5(HRESULT,CreateStream, LPCOLESTR,pwcsName, DWORD,grfMode, DWORD,reserved1, DWORD,reserved2, IStream**,ppstm) \ + ICOM_METHOD5(HRESULT,OpenStream, LPCOLESTR,pwcsName, void*,reserved1, DWORD,grfMode, DWORD,reserved2, IStream**,ppstm) \ + ICOM_METHOD5(HRESULT,CreateStorage, LPCOLESTR,pwcsName, DWORD,grfMode, DWORD,dwStgFmt, DWORD,reserved2, IStorage**,ppstg) \ + ICOM_METHOD6(HRESULT,OpenStorage, LPCOLESTR,pwcsName, IStorage*,pstgPriority, DWORD,grfMode, SNB,snb16Exclude, DWORD,reserved, IStorage**,ppstg) \ + ICOM_METHOD4(HRESULT,CopyTo, DWORD,ciidExclude, const IID*,rgiidExclude, SNB,snb16Exclude, IStorage*,pstgDest) \ + ICOM_METHOD4(HRESULT,MoveElementTo, LPCOLESTR,pwcsName, IStorage*,pstgDest, LPCOLESTR,pwcsNewName, DWORD,grfFlags) \ + ICOM_METHOD1(HRESULT,Commit, DWORD,grfCommitFlags) \ + ICOM_METHOD (HRESULT,Revert) \ + ICOM_METHOD4(HRESULT,EnumElements, DWORD,reserved1, void*,reserved2, DWORD,reserved3, IEnumSTATSTG**,ppenum) \ + ICOM_METHOD1(HRESULT,DestroyElement, LPCOLESTR,pwcsName) \ + ICOM_METHOD2(HRESULT,RenameElement, LPCOLESTR,pwcsOldName, LPCOLESTR,pwcsNewName) \ + ICOM_METHOD4(HRESULT,SetElementTimes,LPCOLESTR,pwcsName, const FILETIME*,pctime, const FILETIME*,patime, const FILETIME*,pmtime) \ + ICOM_METHOD1(HRESULT,SetClass, REFCLSID,clsid) \ + ICOM_METHOD2(HRESULT,SetStateBits, DWORD,grfStateBits, DWORD,grfMask) \ + ICOM_METHOD2(HRESULT,Stat, STATSTG*,pstatstg, DWORD,grfStatFlag) +#define IStorage_IMETHODS \ + IUnknown_IMETHODS \ + IStorage_METHODS +ICOM_DEFINE(IStorage,IUnknown) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IStorage_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IStorage_AddRef(p) ICOM_CALL (AddRef,p) +#define IStorage_Release(p) ICOM_CALL (Release,p) +/*** IStorage methods ***/ +#define IStorage_CreateStream(p,a,b,c,d,e) ICOM_CALL5(CreateStream,p,a,b,c,d,e) +#define IStorage_OpenStream(p,a,b,c,d,e) ICOM_CALL5(OpenStream,p,a,b,c,d,e) +#define IStorage_CreateStorage(p,a,b,c,d,e) ICOM_CALL5(CreateStorage,p,a,b,c,d,e) +#define IStorage_OpenStorage(p,a,b,c,d,e,f) ICOM_CALL6(OpenStorage,p,a,b,c,d,e,f) +#define IStorage_CopyTo(p,a,b,c,d) ICOM_CALL4(CopyTo,p,a,b,c,d) +#define IStorage_MoveElementTo(p,a,b,c,d) ICOM_CALL4(MoveElementTo,p,a,b,c,d) +#define IStorage_Commit(p,a) ICOM_CALL1(Commit,p,a) +#define IStorage_Revert(p) ICOM_CALL (Revert,p) +#define IStorage_EnumElements(p,a,b,c,d) ICOM_CALL4(EnumElements,p,a,b,c,d) +#define IStorage_DestroyElement(p,a) ICOM_CALL1(DestroyElement,p,a) +#define IStorage_RenameElement(p,a,b) ICOM_CALL2(RenameElement,p,a,b) +#define IStorage_SetElementTimes(p,a,b,c,d) ICOM_CALL4(SetElementTimes,p,a,b,c,d) +#define IStorage_SetClass(p,a) ICOM_CALL1(SetClass,p,a) +#define IStorage_SetStateBits(p,a,b) ICOM_CALL2(SetStateBits,p,a,b) +#define IStorage_Stat(p,a,b) ICOM_CALL2(Stat,p,a,b) + + +/***************************************************************************** + * IStream interface + */ +#define ICOM_INTERFACE IStream16 +#define IStream16_METHODS \ + ICOM_METHOD3(HRESULT,Seek, LARGE_INTEGER,dlibMove, DWORD,dwOrigin, ULARGE_INTEGER*,plibNewPosition) \ + ICOM_METHOD1(HRESULT,SetSize, ULARGE_INTEGER,libNewSize) \ + ICOM_METHOD4(HRESULT,CopyTo, IStream16*,pstm, ULARGE_INTEGER,cb, ULARGE_INTEGER*,pcbRead, ULARGE_INTEGER*,pcbWritten) \ + ICOM_METHOD1(HRESULT,Commit, DWORD,grfCommitFlags) \ + ICOM_METHOD (HRESULT,Revert) \ + ICOM_METHOD3(HRESULT,LockRegion, ULARGE_INTEGER,libOffset, ULARGE_INTEGER,cb, DWORD,dwLockType) \ + ICOM_METHOD3(HRESULT,UnlockRegion,ULARGE_INTEGER,libOffset, ULARGE_INTEGER,cb, DWORD,dwLockType) \ + ICOM_METHOD2(HRESULT,Stat, STATSTG*,pstatstg, DWORD,grfStatFlag) \ + ICOM_METHOD1(HRESULT,Clone, IStream16**,ppstm) +#define IStream16_IMETHODS \ + ISequentialStream_IMETHODS \ + IStream16_METHODS +ICOM_DEFINE(IStream16,ISequentialStream) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IStream16_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IStream16_AddRef(p) ICOM_CALL (AddRef,p) +#define IStream16_Release(p) ICOM_CALL (Release,p) +/*** ISequentialStream methods ***/ +#define IStream16_Read(p,a,b,c) ICOM_CALL3(Read,p,a,b,c) +#define IStream16_Write(p,a,b,c) ICOM_CALL3(Write,p,a,b,c) +/*** IStream16 methods ***/ +#define IStream16_Seek(p) ICOM_CALL3(Seek,p) +#define IStream16_SetSize(p,a,b) ICOM_CALL1(SetSize,p,a,b) +#define IStream16_CopyTo(pa,b,c,d) ICOM_CALL4(CopyTo,pa,b,c,d) +#define IStream16_Commit(p,a) ICOM_CALL1(Commit,p,a) +#define IStream16_Revert(p) ICOM_CALL (Revert,p) +#define IStream16_LockRegion(pa,b,c) ICOM_CALL3(LockRegion,pa,b,c) +#define IStream16_UnlockRegion(p,a,b,c) ICOM_CALL3(UnlockRegion,p,a,b,c) +#define IStream16_Stat(p,a,b) ICOM_CALL2(Stat,p,a,b) +#define IStream16_Clone(p,a) ICOM_CALL1(Clone,p,a) + + +#define ICOM_INTERFACE IStream +#define IStream_METHODS \ + ICOM_METHOD3(HRESULT,Seek, LARGE_INTEGER,dlibMove, DWORD,dwOrigin, ULARGE_INTEGER*,plibNewPosition) \ + ICOM_METHOD1(HRESULT,SetSize, ULARGE_INTEGER,libNewSize) \ + ICOM_METHOD4(HRESULT,CopyTo, IStream*,pstm, ULARGE_INTEGER,cb, ULARGE_INTEGER*,pcbRead, ULARGE_INTEGER*,pcbWritten) \ + ICOM_METHOD1(HRESULT,Commit, DWORD,grfCommitFlags) \ + ICOM_METHOD (HRESULT,Revert) \ + ICOM_METHOD3(HRESULT,LockRegion, ULARGE_INTEGER,libOffset, ULARGE_INTEGER,cb, DWORD,dwLockType) \ + ICOM_METHOD3(HRESULT,UnlockRegion,ULARGE_INTEGER,libOffset, ULARGE_INTEGER,cb, DWORD,dwLockType) \ + ICOM_METHOD2(HRESULT,Stat, STATSTG*,pstatstg, DWORD,grfStatFlag) \ + ICOM_METHOD1(HRESULT,Clone, IStream**,ppstm) +#define IStream_IMETHODS \ + ISequentialStream_IMETHODS \ + IStream_METHODS +ICOM_DEFINE(IStream,ISequentialStream) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IStream_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IStream_AddRef(p) ICOM_CALL (AddRef,p) +#define IStream_Release(p) ICOM_CALL (Release,p) +/*** ISequentialStream methods ***/ +#define IStream_Read(p,a,b,c) ICOM_CALL3(Read,p,a,b,c) +#define IStream_Write(p,a,b,c) ICOM_CALL3(Write,p,a,b,c) +/*** IStream methods ***/ +#define IStream_Seek(p,a,b,c) ICOM_CALL3(Seek,p,a,b,c) +#define IStream_SetSize(p,a) ICOM_CALL1(SetSize,p,a) +#define IStream_CopyTo(p,a,b,c,d) ICOM_CALL4(CopyTo,p,a,b,c,d) +#define IStream_Commit(p,a) ICOM_CALL1(Commit,p,a) +#define IStream_Revert(p) ICOM_CALL (Revert,p) +#define IStream_LockRegion(p,a,b,c) ICOM_CALL3(LockRegion,p,a,b,c) +#define IStream_UnlockRegion(p,a,b,c) ICOM_CALL3(UnlockRegion,p,a,b,c) +#define IStream_Stat(p,a,b) ICOM_CALL2(Stat,p,a,b) +#define IStream_Clone(p,a) ICOM_CALL1(Clone,p,a) + + +/***************************************************************************** + * StgXXX API + */ +/* FIXME: many functions are missing */ +HRESULT WINAPI StgCreateDocFile16(LPCOLESTR16 pwcsName,DWORD grfMode,DWORD reserved,IStorage16 **ppstgOpen); +HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName,DWORD grfMode,DWORD reserved,IStorage **ppstgOpen); + +HRESULT WINAPI StgIsStorageFile16(LPCOLESTR16 fn); +HRESULT WINAPI StgIsStorageFile(LPCOLESTR fn); +HRESULT WINAPI StgIsStorageILockBytes(ILockBytes *plkbyt); + +HRESULT WINAPI StgOpenStorage16(const OLECHAR16* pwcsName,IStorage16* pstgPriority,DWORD grfMode,SNB16 snbExclude,DWORD reserved,IStorage16**ppstgOpen); +HRESULT WINAPI StgOpenStorage(const OLECHAR* pwcsName,IStorage* pstgPriority,DWORD grfMode,SNB snbExclude,DWORD reserved,IStorage**ppstgOpen); + +HRESULT WINAPI WriteClassStg(IStorage* pStg, REFCLSID rclsid); +HRESULT WINAPI ReadClassStg(IStorage *pstg,CLSID *pclsid); + +HRESULT WINAPI WriteClassStm(IStream *pStm,REFCLSID rclsid); +HRESULT WINAPI ReadClassStm(IStream *pStm,REFCLSID rclsid); + +HRESULT WINAPI StgCreateDocfileOnILockBytes(ILockBytes *plkbyt,DWORD grfMode, DWORD reserved, IStorage** ppstgOpen); +HRESULT WINAPI StgOpenStorageOnILockBytes(ILockBytes *plkbyt, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen); + +/***************************************************************************** + * Other storage API + */ + +/* FIXME: not implemented */ +BOOL WINAPI CoDosDateTimeToFileTime(WORD nDosDate, WORD nDosTime, FILETIME* lpFileTime); + +/* FIXME: not implemented */ +BOOL WINAPI CoFileTimeToDosDateTime(FILETIME* lpFileTime, WORD* lpDosDate, WORD* lpDosTime); + +HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal); + +HRESULT WINAPI OleSaveToStream(IPersistStream *pPStm,IStream *pStm); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_STORAGE_H */ diff --git a/reactos/include/ole32/obj_webbrowser.h b/reactos/include/ole32/obj_webbrowser.h new file mode 100644 index 00000000000..fb9f3d6ce8d --- /dev/null +++ b/reactos/include/ole32/obj_webbrowser.h @@ -0,0 +1,100 @@ +/* + * Defines the COM interfaces and APIs related to the IE Web browser control + * + * 2001 John R. Sheets (for CodeWeavers) + */ + +#ifndef __WINE_WINE_OBJ_WEBBROWSER_H +#define __WINE_WINE_OBJ_WEBBROWSER_H + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + + +/***************************************************************************** + * Predeclare the interfaces and class IDs + */ +DEFINE_GUID(IID_IWebBrowser, 0xeab22ac1, 0x30c1, 0x11cf, 0xa7, 0xeb, 0x00, 0x00, 0xc0, 0x5b, 0xae, 0x0b); +typedef struct IWebBrowser IWebBrowser, *LPWEBBROWSER; + +DEFINE_GUID(CLSID_WebBrowser, 0x8856f961, 0x340a, 0x11d0, 0xa9, 0x6b, 0x00, 0xc0, 0x4f, 0xd7, 0x05, 0xa2); + +/***************************************************************************** + * IWebBrowser interface + */ +#define ICOM_INTERFACE IWebBrowser +#define IWebBrowser_METHODS \ + ICOM_METHOD(HRESULT,GoBack) \ + ICOM_METHOD(HRESULT,GoForward) \ + ICOM_METHOD(HRESULT,GoHome) \ + ICOM_METHOD(HRESULT,GoSearch) \ + ICOM_METHOD5(HRESULT,Navigate, BSTR*,URL, VARIANT*,Flags, VARIANT*,TargetFrameName, \ + VARIANT*,PostData, VARIANT*,Headers) \ + ICOM_METHOD(HRESULT,Refresh) \ + ICOM_METHOD1(HRESULT,Refresh2, VARIANT*,Level) \ + ICOM_METHOD(HRESULT,Stop) \ + ICOM_METHOD1(HRESULT,get_Application, void**,ppDisp) \ + ICOM_METHOD1(HRESULT,get_Parent, void**,ppDisp) \ + ICOM_METHOD1(HRESULT,get_Container, void**,ppDisp) \ + ICOM_METHOD1(HRESULT,get_Document, void**,ppDisp) \ + ICOM_METHOD1(HRESULT,get_TopLevelContainer, VARIANT*,pBool) \ + ICOM_METHOD1(HRESULT,get_Type, BSTR*,Type) \ + ICOM_METHOD1(HRESULT,get_Left, long*,pl) \ + ICOM_METHOD1(HRESULT,put_Left, long,Left) \ + ICOM_METHOD1(HRESULT,get_Top, long*,pl) \ + ICOM_METHOD1(HRESULT,put_Top, long,Top) \ + ICOM_METHOD1(HRESULT,get_Width, long*,pl) \ + ICOM_METHOD1(HRESULT,put_Width, long,Width) \ + ICOM_METHOD1(HRESULT,get_Height, long*,pl) \ + ICOM_METHOD1(HRESULT,put_Height, long,Height) \ + ICOM_METHOD1(HRESULT,get_LocationName, BSTR*,LocationName) \ + ICOM_METHOD1(HRESULT,get_LocationURL, BSTR*,LocationURL) \ + ICOM_METHOD1(HRESULT,get_Busy, VARIANT*,pBool) +#define IWebBrowser_IMETHODS \ + IDispatch_METHODS \ + IWebBrowser_METHODS +ICOM_DEFINE(IWebBrowser,IDispatch) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IWebBrowser_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IWebBrowser_AddRef(p) ICOM_CALL (AddRef,p) +#define IWebBrowser_Release(p) ICOM_CALL (Release,p) +/*** IDispatch methods ***/ +#define IWebBrowser_GetTypeInfoCount(p,a) ICOM_CALL1 (GetTypeInfoCount,p,a) +#define IWebBrowser_GetTypeInfo(p,a,b,c) ICOM_CALL3 (GetTypeInfo,p,a,b,c) +#define IWebBrowser_GetIDsOfNames(p,a,b,c,d,e) ICOM_CALL5 (GetIDsOfNames,p,a,b,c,d,e) +#define IWebBrowser_Invoke(p,a,b,c,d,e,f,g,h) ICOM_CALL8 (Invoke,p,a,b,c,d,e,f,g,h) +/*** IWebBrowserContainer methods ***/ +#define IWebBrowser_GoBack(p,a) ICOM_CALL1(GoBack,p,a) +#define IWebBrowser_GoForward(p,a) ICOM_CALL1(GoForward,p,a) +#define IWebBrowser_GoHome(p,a) ICOM_CALL1(GoHome,p,a) +#define IWebBrowser_GoSearch(p,a) ICOM_CALL1(GoSearch,p,a) +#define IWebBrowser_Navigate(p,a) ICOM_CALL1(Navigate,p,a) +#define IWebBrowser_Refresh(p,a) ICOM_CALL1(Refresh,p,a) +#define IWebBrowser_Refresh2(p,a) ICOM_CALL1(Refresh2,p,a) +#define IWebBrowser_Stop(p,a) ICOM_CALL1(Stop,p,a) +#define IWebBrowser_get_Application(p,a) ICOM_CALL1(get_Application,p,a) +#define IWebBrowser_get_Parent(p,a) ICOM_CALL1(get_Parent,p,a) +#define IWebBrowser_get_Container(p,a) ICOM_CALL1(get_Container,p,a) +#define IWebBrowser_get_Document(p,a) ICOM_CALL1(get_Document,p,a) +#define IWebBrowser_get_TopLevelContainer(p,a) ICOM_CALL1(get_TopLevelContainer,p,a) +#define IWebBrowser_get_Type(p,a) ICOM_CALL1(get_Type,p,a) +#define IWebBrowser_get_Left(p,a) ICOM_CALL1(get_Left,p,a) +#define IWebBrowser_put_Left(p,a) ICOM_CALL1(put_Left,p,a) +#define IWebBrowser_get_Top(p,a) ICOM_CALL1(get_Top,p,a) +#define IWebBrowser_put_Top(p,a) ICOM_CALL1(put_Top,p,a) +#define IWebBrowser_get_Width(p,a) ICOM_CALL1(get_Width,p,a) +#define IWebBrowser_put_Width(p,a) ICOM_CALL1(put_Width,p,a) +#define IWebBrowser_get_Height(p,a) ICOM_CALL1(get_Height,p,a) +#define IWebBrowser_put_Height(p,a) ICOM_CALL1(put_Height,p,a) +#define IWebBrowser_get_LocationName(p,a) ICOM_CALL1(get_LocationName,p,a) +#define IWebBrowser_get_LocationURL(p,a) ICOM_CALL1(get_LocationURL,p,a) +#define IWebBrowser_get_Busy(p,a) ICOM_CALL1(get_Busy,p,a) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __WINE_WINE_OBJ_WEBBROWSER_H */ diff --git a/reactos/include/ole32/objbase.h b/reactos/include/ole32/objbase.h index e43b5e2c6eb..d2f7cf7672f 100644 --- a/reactos/include/ole32/objbase.h +++ b/reactos/include/ole32/objbase.h @@ -30,8 +30,7 @@ Cambridge, MA 02139, USA. #ifndef _OBJBASE #define _OBJBASE -#include - +#include "guiddef.h" #ifndef EXTERN_C #ifdef __cplusplus @@ -67,36 +66,6 @@ Cambridge, MA 02139, USA. #define WINOLEAPI_(type) STDAPI_(type) #endif -// context in which to create COM objects -typedef enum tagCLSCTX -{ - CLSCTX_INPROC_SERVER = 0x1, - CLSCTX_INPROC_HANDLER = 0x2, - CLSCTX_LOCAL_SERVER = 0x4, - CLSCTX_INPROC_SERVER16 = 0x8, - CLSCTX_REMOTE_SERVER = 0x10, - CLSCTX_INPROC_HANDLER16 = 0x20, - CLSCTX_INPROC_SERVERX86 = 0x40, - CLSCTX_INPROC_HANDLERX86= 0x80, - CLSCTX_ESERVER_HANDLER = 0x100, - CLSCTX_RESERVED = 0x200, - CLSCTX_NO_CODE_DOWNLOAD = 0x400, - CLSCTX_NO_WX86_TRANSLATION = 0x800, - CLSCTX_NO_CUSTOM_MARSHAL = 0x1000, - CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000, - CLSCTX_NO_FAILURE_LOG = 0x4000 -}CLSCTX; -#define CLSCTX_INPROC (CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) - -// COM initialization flags, passed to CoInitialize. -typedef enum tagCOINIT -{ - COINIT_APARTMENTTHREADED = 0x2, // apartement threaded model - COINIT_MULTITHREADED = 0x0, // OLE calls objects on any thread - COINIT_DISABLE_OLE1DDE = 0x4, // don't use DDE for Ole1 support - COINIT_SPEED_OVER_MEMORY = 0x8, // trade memory for speed*/ -}COINIT; - // // COM interface declaration macros [from the wine implementation // @@ -150,47 +119,4 @@ typedef enum tagCOINIT #define DECLARE_INTERFACE_(iface, baseiface) DECLARE_INTERFACE(iface) #endif - - -DEFINE_OLEGUID(IID_IUnknown, 0x00000000L, 0, 0); -DEFINE_OLEGUID(IID_IClassFactory, 0x00000001L, 0, 0); - -// IUnknown -// -DECLARE_INTERFACE(IUnknown) -{ - // *** IUnknown methods *** - STDMETHOD(QueryInterface) (THIS_ REFIID riid, VOID* FAR* ppUnk) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; -}; - -// IClassFactory -// -DECLARE_INTERFACE_(IClassFactory, IUnknown) -{ - // *** IUnknown methods *** - STDMETHOD(QueryInterface) (THIS_ REFIID iid, VOID* FAR* ppvObject) PURE; - STDMETHOD_(ULONG,AddRef) (THIS) PURE; - STDMETHOD_(ULONG,Release) (THIS) PURE; - - // *** IClassFactory methods *** - STDMETHOD(CreateInstance) (THIS_ IUnknown* pUnkOuter, REFIID riid, VOID* FAR* ppvObject) PURE; - STDMETHOD(LockServer) (THIS_ BOOL fLock) PURE; -}; - - -// -// COM API definition -// -WINOLEAPI_(VOID) CoUninitialize(); -WINOLEAPI_(VOID) CoFreeAllLibraries(); -WINOLEAPI_(DWORD) CoBuildVersion(); -WINOLEAPI CoCreateInstance(REFCLSID rclsid, IUnknown* pUnkOuter, DWORD dwClsContext, REFIID riid, VOID** ppv); -WINOLEAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, VOID* pvReserved, REFIID riid, VOID** ppv); -WINOLEAPI CoInitializeEx(VOID* lpReserved, DWORD dwCoInit); -WINOLEAPI CoInitialize(VOID* lpReserved); - - - #endif diff --git a/reactos/include/ole32/ole32.h b/reactos/include/ole32/ole32.h new file mode 100644 index 00000000000..89cad83fdde --- /dev/null +++ b/reactos/include/ole32/ole32.h @@ -0,0 +1,45 @@ +#ifndef ___OLE32_H +#define ___OLE32_H + +#include +#include "wtypes.h" +#include "objbase.h" +#include "obj_base.h" +#include "obj_misc.h" + +#include "obj_storage.h" +#include "obj_moniker.h" +#include "obj_clientserver.h" +#include "obj_dataobject.h" +#include "obj_dragdrop.h" +#include "obj_inplace.h" +#include "obj_oleobj.h" +#include "obj_oleview.h" +#include "obj_cache.h" +#include "obj_marshal.h" + +#include "rpc.h" + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +/* + * OLE version conversion declarations + */ + +typedef struct _OLESTREAM* LPOLESTREAM; +typedef struct _OLESTREAMVTBL { + DWORD CALLBACK (*Get)(LPOLESTREAM,LPSTR,DWORD); + DWORD CALLBACK (*Put)(LPOLESTREAM,LPSTR,DWORD); +} OLESTREAMVTBL; +typedef OLESTREAMVTBL* LPOLESTREAMVTBL; +typedef struct _OLESTREAM { + LPOLESTREAMVTBL lpstbl; +} OLESTREAM; + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __OLE32_H */ diff --git a/reactos/include/ole32/rpc.h b/reactos/include/ole32/rpc.h new file mode 100644 index 00000000000..fe2e48f4628 --- /dev/null +++ b/reactos/include/ole32/rpc.h @@ -0,0 +1,45 @@ +/************************************** + * RPC interface + * + */ +#ifndef __WINE_RPC_H +#define __WINE_RPC_H + +#if !defined(RPC_NO_WINDOWS_H) && !defined(__WINE__) +#include "windows.h" +#endif + +#define __RPC_FAR +#define __RPC_API WINAPI +#define __RPC_USER WINAPI +#define __RPC_STUB WINAPI +#define RPC_ENTRY WINAPI +typedef long RPC_STATUS; + +typedef void* I_RPC_HANDLE; + +#ifndef GUID_DEFINED +#define GUID_DEFINED +typedef struct _GUID +{ + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[8]; +} GUID; +#endif + +#ifndef UUID_DEFINED +#define UUID_DEFINED +typedef GUID UUID; +#endif + +RPC_STATUS RPC_ENTRY UuidCreate(UUID *Uuid); + +#include "rpcdce.h" +/* #include "rpcnsi.h" */ +/* #include "rpcnterr.h" */ +/* #include "excpt.h" */ +//#include "winerror.h" + +#endif /*__WINE_RPC_H */ diff --git a/reactos/include/ole32/rpcdce.h b/reactos/include/ole32/rpcdce.h new file mode 100644 index 00000000000..6698f40e794 --- /dev/null +++ b/reactos/include/ole32/rpcdce.h @@ -0,0 +1,14 @@ +#ifndef __WINE_RPCDCE_H +#define __WINE_RPCDCE_H + +typedef void* RPC_AUTH_IDENTITY_HANDLE; +typedef void* RPC_AUTHZ_HANDLE; +typedef void* RPC_IF_HANDLE; +typedef I_RPC_HANDLE RPC_BINDING_HANDLE; +typedef RPC_BINDING_HANDLE handle_t; +#define rpc_binding_handle_t RPC_BINDING_HANDLE +#define RPC_MGR_EPV void + +#include "rpcdcep.h" + +#endif /*__WINE_RPCDCE_H */ diff --git a/reactos/include/ole32/rpcdcep.h b/reactos/include/ole32/rpcdcep.h new file mode 100644 index 00000000000..ac005248196 --- /dev/null +++ b/reactos/include/ole32/rpcdcep.h @@ -0,0 +1,30 @@ +#ifndef __WINE_RPCDCEP_H +#define __WINE_RPCDCEP_H + + +typedef struct _RPC_VERSION { + unsigned short MajorVersion; + unsigned short MinorVersion; +} RPC_VERSION; + +typedef struct _RPC_SYNTAX_IDENTIFIER { + GUID SyntaxGUID; + RPC_VERSION SyntaxVersion; +} RPC_SYNTAX_IDENTIFIER, *PRPC_SYNTAX_IDENTIFIER; + +typedef struct _RPC_MESSAGE +{ + RPC_BINDING_HANDLE Handle; + unsigned long DataRepresentation; + void* Buffer; + unsigned int BufferLength; + unsigned int ProcNum; + PRPC_SYNTAX_IDENTIFIER TransferSyntax; + void* RpcInterfaceInformation; + void* ReservedForRuntime; + RPC_MGR_EPV* ManagerEpv; + void* ImportContext; + unsigned long RpcFlags; +} RPC_MESSAGE, *PRPC_MESSAGE; + +#endif /*__WINE_RPCDCE_H */ diff --git a/reactos/include/ole32/winerror.h b/reactos/include/ole32/winerror.h index 811dc2c6b0d..ac9a181e614 100644 --- a/reactos/include/ole32/winerror.h +++ b/reactos/include/ole32/winerror.h @@ -29,7 +29,7 @@ Cambridge, MA 02139, USA. ********************************************************************/ #ifndef _WINERROR_H #define _WINERROR_H - +#if 0 // // Return Code macros // @@ -54,5 +54,6 @@ Cambridge, MA 02139, USA. #define E_OUTOFMEMORY 0x8007000EL #define E_INVALIDARG 0x80070057L +#endif #endif \ No newline at end of file diff --git a/reactos/include/ole32/wtypes.h b/reactos/include/ole32/wtypes.h new file mode 100644 index 00000000000..98c31d77b3a --- /dev/null +++ b/reactos/include/ole32/wtypes.h @@ -0,0 +1,208 @@ +/* + * Defines the basic types used by COM interfaces. + */ + +#ifndef __WINE_WTYPES_H +#define __WINE_WTYPES_H + +#if 0 +#include "basetsd.h" +#include "guiddef.h" +#include "rpc.h" +#include "rpcndr.h" +#endif +#include +#include +#include + + +typedef void* HMETAFILEPICT; + +typedef WORD CLIPFORMAT, *LPCLIPFORMAT; + +/* FIXME: does not belong here */ +typedef CHAR OLECHAR16; +typedef LPSTR LPOLESTR16; +typedef LPCSTR LPCOLESTR16; +typedef OLECHAR16 *BSTR16; +typedef BSTR16 *LPBSTR16; +#define OLESTR16(x) x + +typedef WCHAR OLECHAR; +typedef LPWSTR LPOLESTR; +typedef LPCWSTR LPCOLESTR; +typedef OLECHAR *BSTR; +typedef BSTR *LPBSTR; +#ifndef __WINE__ +#define OLESTR(str) WINE_UNICODE_TEXT(str) +#endif + +typedef enum tagDVASPECT +{ + DVASPECT_CONTENT = 1, + DVASPECT_THUMBNAIL = 2, + DVASPECT_ICON = 4, + DVASPECT_DOCPRINT = 8 +} DVASPECT; + +typedef enum tagSTGC +{ + STGC_DEFAULT = 0, + STGC_OVERWRITE = 1, + STGC_ONLYIFCURRENT = 2, + STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE = 4, + STGC_CONSOLIDATE = 8 +} STGC; + +typedef enum tagSTGMOVE +{ + STGMOVE_MOVE = 0, + STGMOVE_COPY = 1, + STGMOVE_SHALLOWCOPY = 2 +} STGMOVE; + + +typedef struct _COAUTHIDENTITY +{ + USHORT* User; + ULONG UserLength; + USHORT* Domain; + ULONG DomainLength; + USHORT* Password; + ULONG PasswordLength; + ULONG Flags; +} COAUTHIDENTITY; + +typedef struct _COAUTHINFO +{ + DWORD dwAuthnSvc; + DWORD dwAuthzSvc; + LPWSTR pwszServerPrincName; + DWORD dwAuthnLevel; + DWORD dwImpersonationLevel; + COAUTHIDENTITY* pAuthIdentityData; + DWORD dwCapabilities; +} COAUTHINFO; + +typedef struct _COSERVERINFO +{ + DWORD dwReserved1; + LPWSTR pwszName; + COAUTHINFO* pAuthInfo; + DWORD dwReserved2; +} COSERVERINFO; + +typedef enum tagCLSCTX +{ + CLSCTX_INPROC_SERVER = 0x1, + CLSCTX_INPROC_HANDLER = 0x2, + CLSCTX_LOCAL_SERVER = 0x4, + CLSCTX_INPROC_SERVER16 = 0x8, + CLSCTX_REMOTE_SERVER = 0x10, + CLSCTX_INPROC_HANDLER16 = 0x20, + CLSCTX_INPROC_SERVERX86 = 0x40, + CLSCTX_INPROC_HANDLERX86 = 0x80, + CLSCTX_ESERVER_HANDLER = 0x100 +} CLSCTX; + +#define CLSCTX_INPROC (CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) +#define CLSCTX_ALL (CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER) +#define CLSCTX_SERVER (CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER) + +typedef enum tagMSHLFLAGS +{ + MSHLFLAGS_NORMAL = 0, + MSHLFLAGS_TABLESTRONG = 1, + MSHLFLAGS_TABLEWEAK = 2, + MSHLFLAGS_NOPING = 4 +} MSHLFLAGS; + +typedef enum tagMSHCTX +{ + MSHCTX_LOCAL = 0, + MSHCTX_NOSHAREDMEM = 1, + MSHCTX_DIFFERENTMACHINE = 2, + MSHCTX_INPROC = 3 +} MSHCTX; + +typedef unsigned short VARTYPE; + +typedef ULONG PROPID; + +#ifndef _tagCY_DEFINED +#define _tagCY_DEFINED + +typedef union tagCY { + struct { +#ifdef BIG_ENDIAN + LONG Hi; + LONG Lo; +#else /* defined(BIG_ENDIAN) */ + ULONG Lo; + LONG Hi; +#endif /* defined(BIG_ENDIAN) */ + } DUMMYSTRUCTNAME; + LONGLONG int64; +} CY; + +#endif /* _tagCY_DEFINED */ + +typedef struct tagDEC { + USHORT wReserved; + union { + struct { + BYTE scale; + BYTE sign; + } DUMMYSTRUCTNAME1; + USHORT signscale; + } DUMMYUNIONNAME1; + ULONG Hi32; + union { + struct { +#ifdef BIG_ENDIAN + ULONG Mid32; + ULONG Lo32; +#else /* defined(BIG_ENDIAN) */ + ULONG Lo32; + ULONG Mid32; +#endif /* defined(BIG_ENDIAN) */ + } DUMMYSTRUCTNAME2; + ULONGLONG Lo64; + } DUMMYUNIONNAME2; +} DECIMAL; + +#define DECIMAL_NEG ((BYTE)0x80) +#ifndef NONAMELESSUNION +#define DECIMAL_SETZERO(d) \ + do {(d).Lo64 = 0; (d).Hi32 = 0; (d).signscale = 0;} while (0) +#else +#define DECIMAL_SETZERO(d) \ + do {(d).u2.Lo64 = 0; (d).Hi32 = 0; (d).u1.signscale = 0;} while (0) +#endif + +/* + * 0 == FALSE and -1 == TRUE + */ +#define VARIANT_TRUE ((VARIANT_BOOL)0xFFFF) +#define VARIANT_FALSE ((VARIANT_BOOL)0x0000) +typedef short VARIANT_BOOL,_VARIANT_BOOL; + +typedef struct tagCLIPDATA +{ + ULONG cbSize; + long ulClipFmt; + BYTE *pClipData; +} CLIPDATA; + +/* Macro to calculate the size of the above pClipData */ +#define CBPCLIPDATA(clipdata) ( (clipdata).cbSize - sizeof((clipdata).ulClipFmt) ) + +typedef LONG SCODE; + +#ifndef _ROTFLAGS_DEFINED +#define _ROTFLAGS_DEFINED +#define ROTFLAGS_REGISTRATIONKEEPSALIVE 0x1 +#define ROTFLAGS_ALLOWANYCLIENT 0x2 +#endif /* !defined(_ROTFLAGS_DEFINED) */ + +#endif /* __WINE_WTYPES_H */ diff --git a/reactos/include/structs.h b/reactos/include/structs.h index 3dbfdc9e7d2..1021e95fbd4 100644 --- a/reactos/include/structs.h +++ b/reactos/include/structs.h @@ -144,14 +144,14 @@ typedef struct _RECT { LONG top; LONG right; LONG bottom; -} RECT, *LPRECT, *PRECT; +} RECT, *LPRECT, *LPCRECT, *PRECT; typedef struct _RECTL { LONG left; LONG top; LONG right; LONG bottom; -} RECTL, *PRECTL; +} RECTL, *LPRECTL, *LPCRECTL, *PRECTL; typedef struct _AppBarData { DWORD cbSize; @@ -4397,6 +4397,19 @@ typedef struct _BLENDFUNCTION { BYTE AlphaFormat; }BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION; +typedef enum _GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard +} GET_FILEEX_INFO_LEVELS; + +typedef struct _WIN32_FILE_ATTRIBUTES_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; +} WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/reactos/include/windows.h b/reactos/include/windows.h index 83718a8692d..332ce0ca8fc 100644 --- a/reactos/include/windows.h +++ b/reactos/include/windows.h @@ -32,6 +32,20 @@ #ifndef _GNU_H_WINDOWS_H #define _GNU_H_WINDOWS_H +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX max +#endif +#ifndef MIN +#define MIN min +#endif + #ifndef RC_INVOKED #include #include diff --git a/reactos/lib/ole32/CoXxx.c b/reactos/lib/ole32/CoXxx.c index 67c97eedc27..5da41efc771 100644 --- a/reactos/lib/ole32/CoXxx.c +++ b/reactos/lib/ole32/CoXxx.c @@ -27,106 +27,44 @@ Cambridge, MA 02139, USA. ********************************************************************/ -#define INITGUID -#include "Ole32.h" + +//#define INITGUID +#include + +#include // // lCOMLockCount is a reference count, when it reaches 0, all COM libraries are freed // static ULONG lCOMLockCount = 0; -/*WINOLEAPI_(ULONG) CoAddRefServerProcess() +WINOLEAPI_(ULONG) CoAddRefServerProcess() { - // not implemented + UNIMPLEMENTED; + return 0L; } WINOLEAPI CoAllowSetForegroundWindow(IUnknown *pUnk, LPVOID lpvReserved) { - // not implemented - return 0L; -}*/ + UNIMPLEMENTED; -// -// The winapi states this function has becaome obsolete -// -WINOLEAPI_(DWORD) CoBuildVersion() -{ - return 0; + return E_FAIL; } -/*WINOLEAPI CoCancelCall(DWORD dwThreadId, ULONG ulTimeout) + +WINOLEAPI CoCancelCall(DWORD dwThreadId, ULONG ulTimeout) { - // not implemented + UNIMPLEMENTED; + return E_FAIL; } WINOLEAPI CoCopyProxy(IUnknown* pProxy, IUnknown** ppCopy) { - // not implemented - return E_FAIL; -} + UNIMPLEMENTED; -WINOLEAPI CoCreateFreeThreadedMarshaler(LPUNKNOWN punkOuter, LPUNKNOWN* ppunkMarshal) -{ - // not implemented - return E_FAIL; -} - -// -// CoCreateGuid creates a uuid -// -WINOLEAPI CoCreateGuid(GUID* pguid) -{ - return UuidCreate(pguid); -} - -// -// CoCreateInstanceEx can call multiple inteerfaces -// -WINOLEAPI CoCreateInstanceEx(REFCLSID Clsid, IUnknown* pUnkOuter, DWORD dwClsCtx, COSERVERINFO* pServerInfo, - DWORD dwCount, MULTI_QI* pResults) -{ - IUnknown* pUnknown = NULL; - HRESULT hr = S_OK; - DWORD nSuccess = 0; - - if((dwCount == 0) || (pResults == NULL)) - return E_INVALIDARG; - - // we do not implement object creation on other machines - if(pServerInfo != NULL) - return E_NOTIMPL; - - // init the pResults structure - for(DWORD i = 0; i < dwCount; i++) - { - pResults[i].pItf = NULL; - pResults[i].hr = E_NOINTERFACE; - } - - // create the object - hr = CoCreateInstance(Clsid, pUnkOuter, dwClsCtx, IID_IUnknown, (void**) &pUnknown); - if(FAILED(hr)) - return hr; - - //Then, query for all the interfaces requested - for(i = 0; i < dwCount; i++) - { - pResults[i].hr = pUnknown->QueryInterface((REFIID) pResults[i].pIID, (void**) &(pResults[i].pItf)); - if(!FAILED(pResults[i].hr)) - nSuccess++; - } - - // clean up - pUnknown->Release(); - if(nSuccess == 0) - return E_NOINTERFACE; - - if(nSuccess != dwCount) - return CO_S_NOTALLINTERFACES; - - return S_OK; + return E_FAIL; } // @@ -134,13 +72,9 @@ WINOLEAPI CoCreateInstanceEx(REFCLSID Clsid, IUnknown* pUnkOuter, DWORD dwClsCtx // WINOLEAPI CoDisableCallCancellation(LPVOID pvReserved) { - return E_FAIL; -} + UNIMPLEMENTED; -WINOLEAPI CoDisconnectObject(LPUNKNOWN pUnk, DWORD dwReserved) -{ - // not implemented - return E_FAIL; + return E_FAIL; } // @@ -148,6 +82,8 @@ WINOLEAPI CoDisconnectObject(LPUNKNOWN pUnk, DWORD dwReserved) // WINOLEAPI_(BOOL) CoDosDateTimeToFileTime(WORD nDosDate, WORD nDosTime, FILETIME* lpFileTime) { + UNIMPLEMENTED; + return TRUE; } @@ -156,15 +92,9 @@ WINOLEAPI_(BOOL) CoDosDateTimeToFileTime(WORD nDosDate, WORD nDosTime, FILETIME* // WINOLEAPI CoEnableCallCancellation(LPVOID pvReserver) { - return E_FAIL; -} + UNIMPLEMENTED; -// -// -// -WINOLEAPI CoFileTimeNow(FILETIME* lpFileTime) -{ - return E_FAIL; + return E_FAIL; } // @@ -172,32 +102,9 @@ WINOLEAPI CoFileTimeNow(FILETIME* lpFileTime) // WINOLEAPI_(BOOL) CoFileTimeToDosDateTime(FILETIME* lpFileTime, LPWORD lpDosDate, LPWORD lpDosTime) { - return E_FAIL; -}*/ + UNIMPLEMENTED; -// -// CoFreeAllLibraries frees all libraries loaded by CoLoadLibrary -// from memory. -// -WINOLEAPI_(VOID) CoFreeAllLibraries() -{ - return; -} -/* -// -// -// -WINOLEAPI_(void) CoFreeLibrary(HINSTANCE hInst) -{ - return; -} - -// -// -// -WINOLEAPI_(void) CoFreeUnusedLibraries() -{ - return; + return E_FAIL; } // @@ -205,7 +112,9 @@ WINOLEAPI_(void) CoFreeUnusedLibraries() // WINOLEAPI CoGetCallContext(REFIID riid, void** ppInterface) { - return E_FAIL; + UNIMPLEMENTED; + + return E_FAIL; } // @@ -213,93 +122,18 @@ WINOLEAPI CoGetCallContext(REFIID riid, void** ppInterface) // WINOLEAPI CoGetCancelObject(DWORD dwThreadId, REFIID iid, void** ppUnk) { - return E_FAIL; -}*/ + UNIMPLEMENTED; -// -// CoCreateInstance creates an instance of some COM object -// -WINOLEAPI CoCreateInstance(REFCLSID rclsid, IUnknown* pUnkOuter, DWORD dwClsContext, REFIID riid, VOID** ppv) -{ - HRESULT hr = S_OK; - IClassFactory* pCF; - - if(ppv == NULL) - return E_POINTER; - - *ppv = NULL; - - // create the class factory - hr = CoGetClassObject(rclsid, dwClsContext, NULL, &IID_IClassFactory, (VOID**) &pCF); - if(FAILED(hr)) - return hr; - - // create one instance of this class - pCF->lpVtbl->CreateInstance(pCF, pUnkOuter, riid, ppv); - pCF->lpVtbl->Release(pCF); - - return hr; + return E_FAIL; } -// -// CoGetClassObject gets the class factory for a specified object -// -WINOLEAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, VOID* pvReserved, REFIID riid, VOID** ppv) -{ - HMODULE hComDll; - HRESULT hr = S_OK; - typedef HRESULT (*PF) (REFCLSID, REFIID, VOID**); - PF fpDllGetClassObject; - - // sanity checks - if(ppv == NULL) - return E_POINTER; - *ppv = NULL; - - // only the CLSCTX_INPROC_SERVER is valid now - if(dwClsContext != CLSCTX_INPROC_SERVER) - return E_FAIL; - - // fix: CoGetClassObject should call CoLoadLibrary as stated in the win32 api docs - hComDll = LoadLibrary("C:\\Com.dll"); - fpDllGetClassObject = (PF) GetProcAddress(hComDll, "DllGetClassObject"); - - - // get the class object - fpDllGetClassObject(rclsid, riid, (VOID**) ppv); - if(*ppv == NULL) - return E_FAIL; - - /* - //HKEY hCLSID; - HKEY hKey; - HKEY hInprocServer; - char szDllPath[MAX_PATH + 1]; - DWORD dwSize; - - - // convert the CLISD to a string - char szCLSID[37] = CLSIDToString(rclsid); - - // get the dll path from the registry - if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &hKey) != ERROR_SUCCESS) - return E_FAIL; - if(RegOpenKeyEx(hKey, szCLSID, 0, KEY_READ, &hKey) != ERROR_SUCCESS) - return E_FAIL; - if(RegOpenKeyEx(hKey, "InprocServer32", 0, KEY_READ, &hInprocServer) != ERROR_SUCCESS) - return E_FAIL; - if(RegQueryValueEx(hInprocServer, NULL, NULL, NULL, (unsigned char*) szDllPath, &dwSize) != ERROR_SUCCESS) - return E_FAIL; - */ - - return hr; -} -/* // // // WINOLEAPI_(DWORD) CoGetCurrentProcess() { + UNIMPLEMENTED; + return 0; } @@ -309,7 +143,9 @@ WINOLEAPI_(DWORD) CoGetCurrentProcess() WINOLEAPI CoGetInstanceFromFile(COSERVERINFO* pServerInfo, CLSID* pClsid, IUnknown* punkOuter, DWORD dwClsCtx, DWORD grfMode, OLECHAR* pwszName, DWORD dwCount, MULTI_QI* pResults) { - return E_FAIL; + UNIMPLEMENTED; + + return E_FAIL; } // @@ -318,7 +154,9 @@ WINOLEAPI CoGetInstanceFromFile(COSERVERINFO* pServerInfo, CLSID* pClsid, IUnkno WINOLEAPI CoGetInstanceFromIStorage(COSERVERINFO* pServerInfo, CLSID* pClsid, IUnknown* punkOuter, DWORD dwClsCtx, IStorage *pstg, DWORD dwCount, MULTI_QI* pResults) { - return E_FAIL; + UNIMPLEMENTED; + + return E_FAIL; } // @@ -326,15 +164,9 @@ WINOLEAPI CoGetInstanceFromIStorage(COSERVERINFO* pServerInfo, CLSID* pClsid, IU // WINOLEAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID iid, LPVOID* ppv) { - return E_FAIL; -} + UNIMPLEMENTED; -// -// -// -WINOLEAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC* ppMalloc) -{ - return S_OK; + return E_FAIL; } // @@ -343,7 +175,9 @@ WINOLEAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC* ppMalloc) WINOLEAPI CoGetMarshalSizeMax(ULONG* pulSize, REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, LPVOID pvdestContext, DWORD mshlflags) { - return E_FAIL; + UNIMPLEMENTED; + + return E_FAIL; } // @@ -351,7 +185,9 @@ WINOLEAPI CoGetMarshalSizeMax(ULONG* pulSize, REFIID riid, LPUNKNOWN pUnk, DWORD // WINOLEAPI CoGetObject(LPCWSTR pszName, BIND_OPTS* pBindOptions, REFIID riid, void** ppv) { - return E_FAIL; + UNIMPLEMENTED; + + return E_FAIL; } // @@ -359,15 +195,9 @@ WINOLEAPI CoGetObject(LPCWSTR pszName, BIND_OPTS* pBindOptions, REFIID riid, voi // WINOLEAPI CoGetObjectContext(REFIID riid, LPVOID FAR* ppv) { - return E_FAIL; -} + UNIMPLEMENTED; -// -// -// -WINOLEAPI CoGetPSClsid(REFIID riid, CLSID* pClsid) -{ - return E_FAIL; + return E_FAIL; } // @@ -376,7 +206,9 @@ WINOLEAPI CoGetPSClsid(REFIID riid, CLSID* pClsid) WINOLEAPI CoGetStandardMarshal(REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, LPVOID pvdestContext, DWORD mshlflags, LPMARSHAL* ppMarshal) { - return E_FAIL; + UNIMPLEMENTED; + + return E_FAIL; } // @@ -384,7 +216,9 @@ WINOLEAPI CoGetStandardMarshal(REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, // WINOLEAPI CoGetStdMarshalEx(LPUNKNOWN pUnkOuter, DWORD smexflags, LPUNKNOWN* ppUnkInner) { - return E_FAIL; + UNIMPLEMENTED; + + return E_FAIL; } // @@ -392,7 +226,9 @@ WINOLEAPI CoGetStdMarshalEx(LPUNKNOWN pUnkOuter, DWORD smexflags, LPUNKNOWN* ppU // WINOLEAPI CoGetTreatAsClass(REFCLSID clsidOld, LPCLSID pClsidNew) { - return E_FAIL; + UNIMPLEMENTED; + + return E_FAIL; } // @@ -400,150 +236,104 @@ WINOLEAPI CoGetTreatAsClass(REFCLSID clsidOld, LPCLSID pClsidNew) // WINOLEAPI CoImpersonateClient() { - return E_FAIL; -}*/ + UNIMPLEMENTED; -// -// CoInitializeEx is the new function to init COM runtime on -// the current thread, setting it's concurrency model, and -// creating an appartment as needed. -// -WINOLEAPI CoInitializeEx(VOID* lpReserved, DWORD dwCoInit) -{ - HRESULT hr = S_OK; - - if(lpReserved != NULL) - return E_INVALIDARG; - - // only apartement threaded COM is supported for now - if(dwCoInit != COINIT_APARTMENTTHREADED) - return E_UNEXPECTED; - - lCOMLockCount++; - return hr; + return E_FAIL; } -// -// CoInitialize is called to initialize the COM runtime on -// the current thread. -// -WINOLEAPI CoInitialize(VOID* lpReserved) +WINOLEAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy) { - // CoInitializeEx is actually the new function to init COM - return CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED); -} + UNIMPLEMENTED; -// -// CoUninitialzie closes the COM runtime on the current thread -// unloads all COM dll's and resources loaded by the thread, and -// forces all RPC connections on this thread to close. -// -WINOLEAPI_(VOID) CoUninitialize() -{ - lCOMLockCount--; - - // free all resources for the last Unitialize call - if(lCOMLockCount == 0) - { - /*RunningObjectTableImpl_UnInitialize(); WINE - - COM_RevokeAllClasses(); - COM_ExternalLockFreeList();*/ - CoFreeAllLibraries(); - } -} -/* -/*WINOLEAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy) -{ return S_OK; } WINOLEAPI CoRevokeMallocSpy() { - return S_OK; -} + UNIMPLEMENTED; -WINOLEAPI CoRegisterClassObject(REFCLSID rclsid, LPUNKNOWN pUnk, DWORD dwClsContext, DWORD flags, LPDWORD lpdwRegister) -{ - return S_OK; -} - -WINOLEAPI CoRevokeClassObject(DWORD dwRegister) -{ - return S_OK; -} - -WINOLEAPI CoResumeClassObjects() -{ return S_OK; } WINOLEAPI CoSuspendClassObjects() { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI_(ULONG) CoReleaseServerProcess() { + UNIMPLEMENTED; + return 0; } -WINOLEAPI CoRegisterPSClsid(IN REFIID riid, IN REFCLSID rclsid) +WINOLEAPI CoRegisterPSClsid(IN REFIID riid, IN REFCLSID rclsid) { + UNIMPLEMENTED; + return S_OK; } -WINOLEAPI CoRegisterSurrogate(IN LPSURROGATE pSurrogate) +#if 0 +WINOLEAPI CoRegisterSurrogate(IN LPSURROGATE pSurrogate) { + UNIMPLEMENTED; + return S_OK; } - +#endif WINOLEAPI CoMarshalInterface(LPSTREAM pStm, REFIID riid, LPUNKNOWN pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags) { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoUnmarshalInterface(LPSTREAM pStm, REFIID riid, LPVOID FAR* ppv) { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoMarshalHresult(LPSTREAM pstm, HRESULT hresult) { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoUnmarshalHresult(LPSTREAM pstm, HRESULT FAR * phresult) { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoReleaseMarshalData(LPSTREAM pStm) { - return S_OK; -} + UNIMPLEMENTED; -WINOLEAPI CoLockObjectExternal(LPUNKNOWN pUnk, BOOL fLock, BOOL fLastUnlockReleases) -{ return S_OK; } WINOLEAPI_(BOOL) CoIsHandlerConnected(LPUNKNOWN pUnk) { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, LPUNKNOWN pUnk, LPSTREAM *ppStm) { - return S_OK; -} + UNIMPLEMENTED; -WINOLEAPI_(HINSTANCE) CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree) -{ - return NULL; + return S_OK; } WINOLEAPI CoInitializeSecurity( @@ -557,6 +347,8 @@ WINOLEAPI CoInitializeSecurity( DWORD dwCapabilities, void *pReserved3 ) { + UNIMPLEMENTED; + return S_OK; } @@ -570,6 +362,8 @@ WINOLEAPI CoQueryProxyBlanket( RPC_AUTH_IDENTITY_HANDLE *pAuthInfo, DWORD *pCapabilites ) { + UNIMPLEMENTED; + return S_OK; } @@ -583,6 +377,8 @@ WINOLEAPI CoSetProxyBlanket( RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities ) { + UNIMPLEMENTED; + return S_OK; } @@ -595,11 +391,16 @@ WINOLEAPI CoQueryClientBlanket( RPC_AUTHZ_HANDLE *pPrivs, DWORD *pCapabilities ) { + UNIMPLEMENTED; + return S_OK; + } WINOLEAPI CoRevertToSelf() { + UNIMPLEMENTED; + return S_OK; } @@ -607,34 +408,48 @@ WINOLEAPI CoQueryAuthenticationServices( DWORD *pcAuthSvc, SOLE_AUTHENTICATION_SERVICE **asAuthSvc ) { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoSwitchCallContext(IUnknown *pNewObject, IUnknown **ppOldObject ) { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoSetCancelObject(IUnknown *pUnk) { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoTestCancel() { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoRegisterMessageFilter( IN LPMESSAGEFILTER lpMessageFilter, OUT LPMESSAGEFILTER FAR* lplpMessageFilter) { + UNIMPLEMENTED; + return S_OK; } +#if 0 WINOLEAPI CoRegisterChannelHook(REFGUID ExtensionUuid, IChannelHook *pChannelHook ) { + UNIMPLEMENTED; + return S_OK; } +#endif WINOLEAPI CoWaitForMultipleHandles(IN DWORD dwFlags, IN DWORD dwTimeout, @@ -642,25 +457,14 @@ WINOLEAPI CoWaitForMultipleHandles(IN DWORD dwFlags, IN LPHANDLE pHandles, OUT LPDWORD lpdwindex) { + UNIMPLEMENTED; + return S_OK; } WINOLEAPI CoTreatAsClass(IN REFCLSID clsidOld, IN REFCLSID clsidNew) { + UNIMPLEMENTED; + return S_OK; } - -WINOLEAPI_(LPVOID) CoTaskMemAlloc(IN SIZE_T cb) -{ - return NULL; -} - -WINOLEAPI_(LPVOID) CoTaskMemRealloc(IN LPVOID pv, IN SIZE_T cb) -{ - return NULL; -} - -WINOLEAPI_(void) CoTaskMemFree(IN LPVOID pv) -{ - return; -}*/ diff --git a/reactos/lib/ole32/DllMain.c b/reactos/lib/ole32/DllMain.c index c132004aafa..d904ec15d69 100644 --- a/reactos/lib/ole32/DllMain.c +++ b/reactos/lib/ole32/DllMain.c @@ -27,7 +27,15 @@ Cambridge, MA 02139, USA. ********************************************************************/ -#include "Ole32.h" +#include + +#include + +#ifdef DBG + +DWORD DebugTraceLevel = MIN_TRACE; + +#endif /* DBG */ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved) { diff --git a/reactos/lib/ole32/Misc.c b/reactos/lib/ole32/Misc.c index b6262b4955f..4252a4ebdcb 100644 --- a/reactos/lib/ole32/Misc.c +++ b/reactos/lib/ole32/Misc.c @@ -27,9 +27,11 @@ Cambridge, MA 02139, USA. ********************************************************************/ -#include "Ole32.h" +#include -/*WINOLEAPI PropVariantClear(PROPVARIANT *pvar){return S_OK;} +#if 0 + +WINOLEAPI PropVariantClear(PROPVARIANT *pvar){return S_OK;} WINOLEAPI FreePropVariantArray( ULONG cVariants, //Count of elements in the structure PROPVARIANT *rgvars //Pointer to the PROPVARIANT structure @@ -91,4 +93,23 @@ WINOLEAPI CLSIDFromProgIDEx (IN LPCOLESTR lpszProgID, OUT LPCLSID lpclsid) WINOLEAPI_(int) StringFromGUID2(IN REFGUID rguid, OUT LPOLESTR lpsz, IN int cchMax) { return S_OK; -}*/ +} + +#endif + +/****************************************************************************** + * IsValidInterface [OLE32.78] + * + * RETURNS + * True, if the passed pointer is a valid interface + */ +BOOL WINAPI IsValidInterface( + LPUNKNOWN punk /* [in] interface to be tested */ +) { + return !( + IsBadReadPtr(punk,4) || + IsBadReadPtr(ICOM_VTBL(punk),4) || + IsBadReadPtr(ICOM_VTBL(punk)->QueryInterface,9) || + IsBadCodePtr((FARPROC)ICOM_VTBL(punk)->QueryInterface) + ); +} diff --git a/reactos/lib/ole32/antimoniker.c b/reactos/lib/ole32/antimoniker.c new file mode 100644 index 00000000000..67e3326d5a6 --- /dev/null +++ b/reactos/lib/ole32/antimoniker.c @@ -0,0 +1,645 @@ +/*************************************************************************************** + * AntiMonikers implementation + * + * Copyright 1999 Noomen Hamza + ***************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + + +/* AntiMoniker data structure */ +typedef struct AntiMonikerImpl{ + + ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/ + + /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether + * two monikers are equal. That's whay IROTData interface is implemented by monikers. + */ + ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/ + + ULONG ref; /* reference counter for this object */ + +} AntiMonikerImpl; + +/********************************************************************************/ +/* AntiMoniker prototype functions : */ + +/* IUnknown prototype functions */ +static HRESULT WINAPI AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject); +static ULONG WINAPI AntiMonikerImpl_AddRef(IMoniker* iface); +static ULONG WINAPI AntiMonikerImpl_Release(IMoniker* iface); + +/* IPersist prototype functions */ +static HRESULT WINAPI AntiMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID); + +/* IPersistStream prototype functions */ +static HRESULT WINAPI AntiMonikerImpl_IsDirty(IMoniker* iface); +static HRESULT WINAPI AntiMonikerImpl_Load(IMoniker* iface, IStream* pStm); +static HRESULT WINAPI AntiMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty); +static HRESULT WINAPI AntiMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize); + +/* IMoniker prototype functions */ +static HRESULT WINAPI AntiMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); +static HRESULT WINAPI AntiMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); +static HRESULT WINAPI AntiMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced); +static HRESULT WINAPI AntiMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite); +static HRESULT WINAPI AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker); +static HRESULT WINAPI AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker); +static HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash); +static HRESULT WINAPI AntiMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning); +static HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pAntiTime); +static HRESULT WINAPI AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk); +static HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix); +static HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath); +static HRESULT WINAPI AntiMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName); +static HRESULT WINAPI AntiMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut); +static HRESULT WINAPI AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys); + +/********************************************************************************/ +/* IROTData prototype functions */ + +/* IUnknown prototype functions */ +static HRESULT WINAPI AntiMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject); +static ULONG WINAPI AntiMonikerROTDataImpl_AddRef(IROTData* iface); +static ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface); + +/* IROTData prototype function */ +static HRESULT WINAPI AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData); + +/* Local function used by AntiMoniker implementation */ +HRESULT WINAPI AntiMonikerImpl_Construct(AntiMonikerImpl* iface); +HRESULT WINAPI AntiMonikerImpl_Destroy(AntiMonikerImpl* iface); + +/********************************************************************************/ +/* Virtual function table for the AntiMonikerImpl class which include IPersist,*/ +/* IPersistStream and IMoniker functions. */ +static ICOM_VTABLE(IMoniker) VT_AntiMonikerImpl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + AntiMonikerImpl_QueryInterface, + AntiMonikerImpl_AddRef, + AntiMonikerImpl_Release, + AntiMonikerImpl_GetClassID, + AntiMonikerImpl_IsDirty, + AntiMonikerImpl_Load, + AntiMonikerImpl_Save, + AntiMonikerImpl_GetSizeMax, + AntiMonikerImpl_BindToObject, + AntiMonikerImpl_BindToStorage, + AntiMonikerImpl_Reduce, + AntiMonikerImpl_ComposeWith, + AntiMonikerImpl_Enum, + AntiMonikerImpl_IsEqual, + AntiMonikerImpl_Hash, + AntiMonikerImpl_IsRunning, + AntiMonikerImpl_GetTimeOfLastChange, + AntiMonikerImpl_Inverse, + AntiMonikerImpl_CommonPrefixWith, + AntiMonikerImpl_RelativePathTo, + AntiMonikerImpl_GetDisplayName, + AntiMonikerImpl_ParseDisplayName, + AntiMonikerImpl_IsSystemMoniker +}; + +/********************************************************************************/ +/* Virtual function table for the IROTData class. */ +static ICOM_VTABLE(IROTData) VT_ROTDataImpl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + AntiMonikerROTDataImpl_QueryInterface, + AntiMonikerROTDataImpl_AddRef, + AntiMonikerROTDataImpl_Release, + AntiMonikerROTDataImpl_GetComparaisonData +}; + +/******************************************************************************* + * AntiMoniker_QueryInterface + *******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject) +{ + ICOM_THIS(AntiMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,riid,ppvObject)); + + /* Perform a sanity check on the parameters.*/ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* Initialize the return parameter */ + *ppvObject = 0; + + /* Compare the riid with the interface IDs implemented by this object.*/ + if (IsEqualIID(&IID_IUnknown, riid) || + IsEqualIID(&IID_IPersist, riid) || + IsEqualIID(&IID_IPersistStream, riid) || + IsEqualIID(&IID_IMoniker, riid) + ) + *ppvObject = iface; + else if (IsEqualIID(&IID_IROTData, riid)) + *ppvObject = (IROTData*)&(This->lpvtbl2); + + /* Check that we obtained an interface.*/ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* Query Interface always increases the reference count by one when it is successful */ + AntiMonikerImpl_AddRef(iface); + + return S_OK; +} + +/****************************************************************************** + * AntiMoniker_AddRef + ******************************************************************************/ +ULONG WINAPI AntiMonikerImpl_AddRef(IMoniker* iface) +{ + ICOM_THIS(AntiMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + return ++(This->ref); +} + +/****************************************************************************** + * AntiMoniker_Release + ******************************************************************************/ +ULONG WINAPI AntiMonikerImpl_Release(IMoniker* iface) +{ + ICOM_THIS(AntiMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + This->ref--; + + /* destroy the object if there's no more reference on it */ + if (This->ref==0){ + + AntiMonikerImpl_Destroy(This); + + return 0; + } + return This->ref;; +} + +/****************************************************************************** + * AntiMoniker_GetClassID + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID) +{ + Print(MAX_TRACE, ("(%p,%p),stub!\n",iface,pClassID)); + + if (pClassID==NULL) + return E_POINTER; + + *pClassID = CLSID_AntiMoniker; + + return S_OK; +} + +/****************************************************************************** + * AntiMoniker_IsDirty + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_IsDirty(IMoniker* iface) +{ + /* Note that the OLE-provided implementations of the IPersistStream::IsDirty + method in the OLE-provided moniker interfaces always return S_FALSE because + their internal state never changes. */ + + Print(MAX_TRACE, ("(%p)\n",iface)); + + return S_FALSE; +} + +/****************************************************************************** + * AntiMoniker_Load + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_Load(IMoniker* iface,IStream* pStm) +{ + DWORD constant=1,dwbuffer; + HRESULT res; + + /* data read by this function is only a DWORD constant (must be 1) ! */ + res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),NULL); + + if (SUCCEEDED(res)&& dwbuffer!=constant) + return E_FAIL; + + return res; +} + +/****************************************************************************** + * AntiMoniker_Save + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty) +{ + DWORD constant=1; + HRESULT res; + + /* data writen by this function is only a DWORD constant seted to 1 ! */ + res=IStream_Write(pStm,&constant,sizeof(constant),NULL); + + return res; +} + +/****************************************************************************** + * AntiMoniker_GetSizeMax + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_GetSizeMax(IMoniker* iface, + ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */ +{ + Print(MAX_TRACE, ("(%p,%p)\n",iface,pcbSize)); + + if (pcbSize!=NULL) + return E_POINTER; + + /* for more details see AntiMonikerImpl_Save coments */ + + /* Normaly the sizemax must be the size of DWORD ! but I tested this function it ususlly return 16 bytes */ + /* more than the number of bytes used by AntiMoniker::Save function */ + pcbSize->u.LowPart = sizeof(DWORD)+16; + + pcbSize->u.HighPart=0; + + return S_OK; +} + +/****************************************************************************** + * AntiMoniker_Construct (local function) + *******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_Construct(AntiMonikerImpl* This) +{ + + Print(MAX_TRACE, ("(%p)\n",This)); + + /* Initialize the virtual fgunction table. */ + This->lpvtbl1 = &VT_AntiMonikerImpl; + This->lpvtbl2 = &VT_ROTDataImpl; + This->ref = 0; + + return S_OK; +} + +/****************************************************************************** + * AntiMoniker_Destroy (local function) + *******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_Destroy(AntiMonikerImpl* This) +{ + Print(MAX_TRACE, ("(%p)\n",This)); + + return HeapFree(GetProcessHeap(),0,This); +} + +/****************************************************************************** + * AntiMoniker_BindToObject + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_BindToObject(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvResult) +{ + Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult)); + return E_NOTIMPL; +} + +/****************************************************************************** + * AntiMoniker_BindToStorage + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_BindToStorage(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvResult) +{ + Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult)); + return E_NOTIMPL; +} + +/****************************************************************************** + * AntiMoniker_Reduce + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_Reduce(IMoniker* iface, + IBindCtx* pbc, + DWORD dwReduceHowFar, + IMoniker** ppmkToLeft, + IMoniker** ppmkReduced) +{ + Print(MAX_TRACE, ("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced)); + + if (ppmkReduced==NULL) + return E_POINTER; + + AntiMonikerImpl_AddRef(iface); + + *ppmkReduced=iface; + + return MK_S_REDUCED_TO_SELF; +} +/****************************************************************************** + * AntiMoniker_ComposeWith + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_ComposeWith(IMoniker* iface, + IMoniker* pmkRight, + BOOL fOnlyIfNotGeneric, + IMoniker** ppmkComposite) +{ + + Print(MAX_TRACE, ("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite)); + + if ((ppmkComposite==NULL)||(pmkRight==NULL)) + return E_POINTER; + + *ppmkComposite=0; + + if (fOnlyIfNotGeneric) + return MK_E_NEEDGENERIC; + else + return CreateGenericComposite(iface,pmkRight,ppmkComposite); +} + +/****************************************************************************** + * AntiMoniker_Enum + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) +{ + Print(MAX_TRACE, ("(%p,%d,%p)\n",iface,fForward,ppenumMoniker)); + + if (ppenumMoniker == NULL) + return E_POINTER; + + *ppenumMoniker = NULL; + + return S_OK; +} + +/****************************************************************************** + * AntiMoniker_IsEqual + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) +{ + DWORD mkSys; + + Print(MAX_TRACE, ("(%p,%p)\n",iface,pmkOtherMoniker)); + + if (pmkOtherMoniker==NULL) + return S_FALSE; + + IMoniker_IsSystemMoniker(pmkOtherMoniker,&mkSys); + + if (mkSys==MKSYS_ANTIMONIKER) + return S_OK; + else + return S_FALSE; +} + +/****************************************************************************** + * AntiMoniker_Hash + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) +{ + if (pdwHash==NULL) + return E_POINTER; + + *pdwHash=0; + + return S_OK; +} + +/****************************************************************************** + * AntiMoniker_IsRunning + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_IsRunning(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + IMoniker* pmkNewlyRunning) +{ + IRunningObjectTable* rot; + HRESULT res; + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning)); + + if (pbc==NULL) + return E_INVALIDARG; + + res=IBindCtx_GetRunningObjectTable(pbc,&rot); + + if (FAILED(res)) + return res; + + res = IRunningObjectTable_IsRunning(rot,iface); + + IRunningObjectTable_Release(rot); + + return res; +} + +/****************************************************************************** + * AntiMoniker_GetTimeOfLastChange + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + FILETIME* pAntiTime) +{ + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pAntiTime)); + return E_NOTIMPL; +} + +/****************************************************************************** + * AntiMoniker_Inverse + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) +{ + Print(MAX_TRACE, ("(%p,%p)\n",iface,ppmk)); + + if (ppmk==NULL) + return E_POINTER; + + *ppmk=0; + + return MK_E_NOINVERSE; +} + +/****************************************************************************** + * AntiMoniker_CommonPrefixWith + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) +{ + DWORD mkSys; + + IMoniker_IsSystemMoniker(pmkOther,&mkSys); + + if(mkSys==MKSYS_ITEMMONIKER){ + + IMoniker_AddRef(iface); + + *ppmkPrefix=iface; + + IMoniker_AddRef(iface); + + return MK_S_US; + } + else + return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix); +} + +/****************************************************************************** + * AntiMoniker_RelativePathTo + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) +{ + Print(MAX_TRACE, ("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath)); + + if (ppmkRelPath==NULL) + return E_POINTER; + + IMoniker_AddRef(pmOther); + + *ppmkRelPath=pmOther; + + return MK_S_HIM; +} + +/****************************************************************************** + * AntiMoniker_GetDisplayName + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_GetDisplayName(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + LPOLESTR *ppszDisplayName) +{ + WCHAR back[]={'\\','.','.',0}; + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName)); + + if (ppszDisplayName==NULL) + return E_POINTER; + + if (pmkToLeft!=NULL){ + Print(MIN_TRACE, ("() pmkToLeft!=NULL not implemented \n")); + return E_NOTIMPL; + } + + *ppszDisplayName=CoTaskMemAlloc(sizeof(back)); + + if (*ppszDisplayName==NULL) + return E_OUTOFMEMORY; + + lstrcpyW(*ppszDisplayName,back); + + return S_OK; +} + +/****************************************************************************** + * AntiMoniker_ParseDisplayName + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_ParseDisplayName(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + LPOLESTR pszDisplayName, + ULONG* pchEaten, + IMoniker** ppmkOut) +{ + Print(MAX_TRACE, ("(%p,%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut)); + return E_NOTIMPL; +} + +/****************************************************************************** + * AntiMoniker_IsSystemMoniker + ******************************************************************************/ +HRESULT WINAPI AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys) +{ + Print(MAX_TRACE, ("(%p,%p)\n",iface,pwdMksys)); + + if (!pwdMksys) + return E_POINTER; + + (*pwdMksys)=MKSYS_ANTIMONIKER; + + return S_OK; +} + +/******************************************************************************* + * AntiMonikerIROTData_QueryInterface + *******************************************************************************/ +HRESULT WINAPI AntiMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject) +{ + + ICOM_THIS_From_IROTData(IMoniker, iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",iface,riid,ppvObject)); + + return AntiMonikerImpl_QueryInterface(This, riid, ppvObject); +} + +/*********************************************************************** + * AntiMonikerIROTData_AddRef + */ +ULONG WINAPI AntiMonikerROTDataImpl_AddRef(IROTData *iface) +{ + ICOM_THIS_From_IROTData(IMoniker, iface); + + Print(MAX_TRACE, ("(%p)\n",iface)); + + return AntiMonikerImpl_AddRef(This); +} + +/*********************************************************************** + * AntiMonikerIROTData_Release + */ +ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface) +{ + ICOM_THIS_From_IROTData(IMoniker, iface); + + Print(MAX_TRACE, ("(%p)\n",iface)); + + return AntiMonikerImpl_Release(This); +} + +/****************************************************************************** + * AntiMonikerIROTData_GetComparaisonData + ******************************************************************************/ +HRESULT WINAPI AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface, + BYTE* pbData, + ULONG cbMax, + ULONG* pcbData) +{ + Print(MIN_TRACE, ("(),stub!\n")); + return E_NOTIMPL; +} + +/****************************************************************************** + * CreateAntiMoniker [OLE.55] + ******************************************************************************/ +HRESULT WINAPI CreateAntiMoniker(LPMONIKER * ppmk) +{ + AntiMonikerImpl* newAntiMoniker = 0; + HRESULT hr = S_OK; + IID riid=IID_IMoniker; + + Print(MAX_TRACE, ("(%p)\n",ppmk)); + + newAntiMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(AntiMonikerImpl)); + + if (newAntiMoniker == 0) + return STG_E_INSUFFICIENTMEMORY; + + hr = AntiMonikerImpl_Construct(newAntiMoniker); + + if (FAILED(hr)){ + + HeapFree(GetProcessHeap(),0,newAntiMoniker); + return hr; + } + + hr = AntiMonikerImpl_QueryInterface((IMoniker*)newAntiMoniker,&riid,(void**)ppmk); + + return hr; +} diff --git a/reactos/lib/ole32/bindctx.c b/reactos/lib/ole32/bindctx.c new file mode 100644 index 00000000000..1a6e24e4d93 --- /dev/null +++ b/reactos/lib/ole32/bindctx.c @@ -0,0 +1,544 @@ +/*************************************************************************************** + * BindCtx implementation + * + * Copyright 1999 Noomen Hamza + ***************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + + +/* represent the first size table and it's increment block size */ +#define BLOCK_TAB_SIZE 10 +#define MAX_TAB_SIZE 0xFFFFFFFF + +/* data structure of the BindCtx table elements */ +typedef struct BindCtxObject{ + + IUnknown* pObj; /* point on a bound object */ + + LPOLESTR pkeyObj; /* key associated to this bound object */ + + BYTE regType; /* registration type: 1 if RegisterObjectParam and 0 if RegisterObjectBound */ + +} BindCtxObject; + +/* BindCtx data strucrture */ +typedef struct BindCtxImpl{ + + ICOM_VFIELD(IBindCtx); /* VTable relative to the IBindCtx interface.*/ + + ULONG ref; /* reference counter for this object */ + + BindCtxObject* bindCtxTable; /* this is a table in which all bounded objects are stored*/ + DWORD bindCtxTableLastIndex; /* first free index in the table */ + DWORD bindCtxTableSize; /* size table */ + + BIND_OPTS2 bindOption2; /* a structure which contains the bind options*/ + +} BindCtxImpl; + +/* IBindCtx prototype functions : */ + +/* IUnknown functions*/ +static HRESULT WINAPI BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject); +static ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface); +static ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface); +/* IBindCtx functions */ +static HRESULT WINAPI BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk); +static HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk); +static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface); +static HRESULT WINAPI BindCtxImpl_SetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts); +static HRESULT WINAPI BindCtxImpl_GetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts); +static HRESULT WINAPI BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot); +static HRESULT WINAPI BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk); +static HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk); +static HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** ppenum); +static HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR pszkey); +/* Local functions*/ +HRESULT WINAPI BindCtxImpl_Construct(BindCtxImpl* This); +HRESULT WINAPI BindCtxImpl_Destroy(BindCtxImpl* This); +HRESULT WINAPI BindCtxImpl_GetObjectIndex(BindCtxImpl* This,IUnknown* punk,LPOLESTR pszkey,DWORD *index); + +/* Virtual function table for the BindCtx class. */ +static ICOM_VTABLE(IBindCtx) VT_BindCtxImpl = + { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + BindCtxImpl_QueryInterface, + BindCtxImpl_AddRef, + BindCtxImpl_Release, + BindCtxImpl_RegisterObjectBound, + BindCtxImpl_RevokeObjectBound, + BindCtxImpl_ReleaseBoundObjects, + BindCtxImpl_SetBindOptions, + BindCtxImpl_GetBindOptions, + BindCtxImpl_GetRunningObjectTable, + BindCtxImpl_RegisterObjectParam, + BindCtxImpl_GetObjectParam, + BindCtxImpl_EnumObjectParam, + BindCtxImpl_RevokeObjectParam +}; + +/******************************************************************************* + * BindCtx_QueryInterface + *******************************************************************************/ +HRESULT WINAPI BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject) +{ + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,riid,ppvObject)); + + /* Perform a sanity check on the parameters.*/ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* Initialize the return parameter.*/ + *ppvObject = 0; + + /* Compare the riid with the interface IDs implemented by this object.*/ + if (IsEqualIID(&IID_IUnknown, riid)) + *ppvObject = (IBindCtx*)This; + else + if (IsEqualIID(&IID_IBindCtx, riid)) + *ppvObject = (IBindCtx*)This; + + /* Check that we obtained an interface.*/ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* Query Interface always increases the reference count by one when it is successful */ + BindCtxImpl_AddRef(iface); + + return S_OK; +} + +/****************************************************************************** + * BindCtx_AddRef + ******************************************************************************/ +ULONG WINAPI BindCtxImpl_AddRef(IBindCtx* iface) +{ + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + return ++(This->ref); +} + +/****************************************************************************** + * BindCtx_Release + ******************************************************************************/ +ULONG WINAPI BindCtxImpl_Release(IBindCtx* iface) +{ + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",This);) + + This->ref--; + + if (This->ref==0){ + + /* release all registered objects */ + BindCtxImpl_ReleaseBoundObjects((IBindCtx*)This); + + BindCtxImpl_Destroy(This); + + return 0; + } + return This->ref;; +} + + +/****************************************************************************** + * BindCtx_Construct (local function) + *******************************************************************************/ +HRESULT WINAPI BindCtxImpl_Construct(BindCtxImpl* This) +{ + Print(MAX_TRACE, ("(%p)\n",This)); + + /* Initialize the virtual function table.*/ + ICOM_VTBL(This) = &VT_BindCtxImpl; + This->ref = 0; + + /* Initialize the BIND_OPTS2 structure */ + This->bindOption2.cbStruct = sizeof(BIND_OPTS2); + This->bindOption2.grfFlags = 0; + This->bindOption2.grfMode = STGM_READWRITE; + This->bindOption2.dwTickCountDeadline = 0; + + This->bindOption2.dwTrackFlags = 0; + This->bindOption2.dwClassContext = CLSCTX_SERVER; + This->bindOption2.locale = 1033; + This->bindOption2.pServerInfo = 0; + + /* Initialize the bindctx table */ + This->bindCtxTableSize=BLOCK_TAB_SIZE; + This->bindCtxTableLastIndex=0; + This->bindCtxTable= HeapAlloc(GetProcessHeap(), 0,This->bindCtxTableSize*sizeof(BindCtxObject)); + + if (This->bindCtxTable==NULL) + return E_OUTOFMEMORY; + + return S_OK; +} + +/****************************************************************************** + * BindCtx_Destroy (local function) + *******************************************************************************/ +HRESULT WINAPI BindCtxImpl_Destroy(BindCtxImpl* This) +{ + Print(MAX_TRACE, ("(%p)\n",This)); + + /* free the table space memory */ + HeapFree(GetProcessHeap(),0,This->bindCtxTable); + + /* free the bindctx structure */ + HeapFree(GetProcessHeap(),0,This); + + return S_OK; +} + + +/****************************************************************************** + * BindCtx_RegisterObjectBound + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk) +{ + + ICOM_THIS(BindCtxImpl,iface); + DWORD lastIndex=This->bindCtxTableLastIndex; + BindCtxObject cell; + + Print(MAX_TRACE, ("(%p,%p)\n",This,punk)); + + if (punk==NULL) + return E_POINTER; + + IUnknown_AddRef(punk); + + /* put the object in the first free element in the table */ + This->bindCtxTable[lastIndex].pObj = punk; + This->bindCtxTable[lastIndex].pkeyObj = NULL; + This->bindCtxTable[lastIndex].regType = 0; + cell=This->bindCtxTable[lastIndex]; + lastIndex= ++This->bindCtxTableLastIndex; + + if (lastIndex == This->bindCtxTableSize){ /* the table is full so it must be resized */ + + if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){ + Print(MIN_TRACE, ("This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize)); + return E_FAIL; +} + + This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */ + + This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable, + This->bindCtxTableSize * sizeof(BindCtxObject)); + if (!This->bindCtxTable) + return E_OUTOFMEMORY; + } + return S_OK; +} + +/****************************************************************************** + * BindCtx_RevokeObjectBound + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk) +{ + DWORD index,j; + + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p,%p)\n",This,punk)); + + /* check if the object was registred or not */ + if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE) + + return MK_E_NOTBOUND; + + IUnknown_Release(This->bindCtxTable[index].pObj); + + /* left-shift all elements in the right side of the current revoked object */ + for(j=index; jbindCtxTableLastIndex-1; j++) + This->bindCtxTable[j]= This->bindCtxTable[j+1]; + + This->bindCtxTableLastIndex--; + + return S_OK; +} + +/****************************************************************************** + * BindCtx_ReleaseBoundObjects + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx* iface) +{ + DWORD i; + + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + for(i=0;ibindCtxTableLastIndex;i++) + IUnknown_Release(This->bindCtxTable[i].pObj); + + This->bindCtxTableLastIndex = 0; + + return S_OK; +} + +/****************************************************************************** + * BindCtx_SetBindOptions + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_SetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts) +{ + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p,%p)\n",This,pbindopts)); + + if (pbindopts==NULL) + return E_POINTER; + + if (pbindopts->cbStruct > sizeof(BIND_OPTS2)) + { + Print(MID_TRACE, ("invalid size\n")); + return E_INVALIDARG; /* FIXME : not verified */ + } + memcpy(&This->bindOption2, pbindopts, pbindopts->cbStruct); + return S_OK; +} + +/****************************************************************************** + * BindCtx_GetBindOptions + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_GetBindOptions(IBindCtx* iface,LPBIND_OPTS2 pbindopts) +{ + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p,%p)\n",This,pbindopts)); + + if (pbindopts==NULL) + return E_POINTER; + + if (pbindopts->cbStruct > sizeof(BIND_OPTS2)) + { + Print(MID_TRACE, ("invalid size\n")); + return E_INVALIDARG; /* FIXME : not verified */ + } + memcpy(pbindopts, &This->bindOption2, pbindopts->cbStruct); + return S_OK; +} + +/****************************************************************************** + * BindCtx_GetRunningObjectTable + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_GetRunningObjectTable(IBindCtx* iface,IRunningObjectTable** pprot) +{ + HRESULT res; + + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p,%p)\n",This,pprot)); + + if (pprot==NULL) + return E_POINTER; + + res=GetRunningObjectTable(0, pprot); + + return res; +} + +/****************************************************************************** + * BindCtx_RegisterObjectParam + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk) +{ + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,pszkey,punk)); + + if (punk==NULL) + return E_INVALIDARG; + + IUnknown_AddRef(punk); + + This->bindCtxTable[This->bindCtxTableLastIndex].pObj = punk; + This->bindCtxTable[This->bindCtxTableLastIndex].regType = 1; + + if (pszkey==NULL) + + This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj=NULL; + + else{ + + This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj= + HeapAlloc(GetProcessHeap(),0,(sizeof(WCHAR)*(1+lstrlenW(pszkey)))); + + if (This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj==NULL) + return E_OUTOFMEMORY; + lstrcpyW(This->bindCtxTable[This->bindCtxTableLastIndex].pkeyObj,pszkey); +} + + This->bindCtxTableLastIndex++; + + if (This->bindCtxTableLastIndex == This->bindCtxTableSize){ /* table is full ! must be resized */ + + This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */ + + if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){ + Print(MIN_TRACE, ("This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize)); + return E_FAIL; + } + This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable, + This->bindCtxTableSize * sizeof(BindCtxObject)); + if (!This->bindCtxTable) + return E_OUTOFMEMORY; + } + return S_OK; +} +/****************************************************************************** + * BindCtx_GetObjectParam + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_GetObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown** punk) +{ + DWORD index; + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,pszkey,punk)); + + if (punk==NULL) + return E_POINTER; + + *punk=0; + + if (BindCtxImpl_GetObjectIndex(This,NULL,pszkey,&index)==S_FALSE) + return E_FAIL; + + IUnknown_AddRef(This->bindCtxTable[index].pObj); + + *punk = This->bindCtxTable[index].pObj; + + return S_OK; +} + +/****************************************************************************** + * BindCtx_RevokeObjectParam + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR ppenum) +{ + DWORD index,j; + + ICOM_THIS(BindCtxImpl,iface); + + Print(MAX_TRACE, ("(%p,%p)\n",This,ppenum)); + + if (BindCtxImpl_GetObjectIndex(This,NULL,ppenum,&index)==S_FALSE) + return E_FAIL; + + /* release the object if it's found */ + IUnknown_Release(This->bindCtxTable[index].pObj); + + /* remove the object from the table with a left-shifting of all objects in the right side */ + for(j=index; jbindCtxTableLastIndex-1; j++) + This->bindCtxTable[j]= This->bindCtxTable[j+1]; + + This->bindCtxTableLastIndex--; + + return S_OK; +} + +/****************************************************************************** + * BindCtx_EnumObjectParam + ******************************************************************************/ +HRESULT WINAPI BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** pszkey) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/******************************************************************************** + * GetObjectIndex (local function) + ********************************************************************************/ +HRESULT WINAPI BindCtxImpl_GetObjectIndex(BindCtxImpl* This, + IUnknown* punk, + LPOLESTR pszkey, + DWORD *index) +{ + + DWORD i; + BYTE found=0; + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",This,punk,pszkey,index)); + + if (punk==NULL) + /* search object identified by a register key */ + for(i=0; ( (ibindCtxTableLastIndex) && (!found));i++){ + + if(This->bindCtxTable[i].regType==1){ + + if ( ( (This->bindCtxTable[i].pkeyObj==NULL) && (pszkey==NULL) ) || + ( (This->bindCtxTable[i].pkeyObj!=NULL) && + (pszkey!=NULL) && + (lstrcmpW(This->bindCtxTable[i].pkeyObj,pszkey)==0) + ) + ) + + found=1; + } + } + else + /* search object identified by a moniker*/ + for(i=0; ( (ibindCtxTableLastIndex) && (!found));i++) + if(This->bindCtxTable[i].pObj==punk) + found=1; + + if (index != NULL) + *index=i-1; + + if (found) + return S_OK; + else + return S_FALSE; +} + +/****************************************************************************** + * CreateBindCtx16 + ******************************************************************************/ +HRESULT WINAPI CreateBindCtx16(DWORD reserved, LPBC * ppbc) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/****************************************************************************** + * CreateBindCtx + ******************************************************************************/ +HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc) +{ + BindCtxImpl* newBindCtx = 0; + HRESULT hr; + IID riid=IID_IBindCtx; + + Print(MAX_TRACE, ("(%ld,%p)\n",reserved,ppbc)); + + newBindCtx = HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl)); + + if (newBindCtx == 0) + return E_OUTOFMEMORY; + + hr = BindCtxImpl_Construct(newBindCtx); + + if (FAILED(hr)){ + + HeapFree(GetProcessHeap(),0,newBindCtx); + return hr; + } + + hr = BindCtxImpl_QueryInterface((IBindCtx*)newBindCtx,&riid,(void**)ppbc); + + return hr; +} diff --git a/reactos/lib/ole32/compobj.c b/reactos/lib/ole32/compobj.c new file mode 100644 index 00000000000..534937bf625 --- /dev/null +++ b/reactos/lib/ole32/compobj.c @@ -0,0 +1,2060 @@ +/* + * COMPOBJ library + * + * Copyright 1995 Martin von Loewis + * Copyright 1998 Justin Bradford + * Copyright 1999 Francis Beaudet + * Copyright 1999 Sylvain St-Germain + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +/**************************************************************************** + * COM External Lock structures and methods declaration + * + * This api provides a linked list to managed external references to + * COM objects. + * + * The public interface consists of three calls: + * COM_ExternalLockAddRef + * COM_ExternalLockRelease + * COM_ExternalLockFreeList + */ + +#define EL_END_OF_LIST 0 +#define EL_NOT_FOUND 0 + +/* + * Declaration of the static structure that manage the + * external lock to COM objects. + */ +typedef struct COM_ExternalLock COM_ExternalLock; +typedef struct COM_ExternalLockList COM_ExternalLockList; + +struct COM_ExternalLock +{ + IUnknown *pUnk; /* IUnknown referenced */ + ULONG uRefCount; /* external lock counter to IUnknown object*/ + COM_ExternalLock *next; /* Pointer to next element in list */ +}; + +struct COM_ExternalLockList +{ + COM_ExternalLock *head; /* head of list */ +}; + +/* + * Declaration and initialization of the static structure that manages + * the external lock to COM objects. + */ +static COM_ExternalLockList elList = { EL_END_OF_LIST }; + +/* + * Public Interface to the external lock list + */ +static void COM_ExternalLockFreeList(); +static void COM_ExternalLockAddRef(IUnknown *pUnk); +static void COM_ExternalLockRelease(IUnknown *pUnk, BOOL bRelAll); +void COM_ExternalLockDump(); /* testing purposes, not static to avoid warning */ + +/* + * Private methods used to managed the linked list + */ +static BOOL COM_ExternalLockInsert( + IUnknown *pUnk); + +static void COM_ExternalLockDelete( + COM_ExternalLock *element); + +static COM_ExternalLock* COM_ExternalLockFind( + IUnknown *pUnk); + +static COM_ExternalLock* COM_ExternalLockLocate( + COM_ExternalLock *element, + IUnknown *pUnk); + +/**************************************************************************** + * This section defines variables internal to the COM module. + * + * TODO: Most of these things will have to be made thread-safe. + */ +HINSTANCE COMPOBJ_hInstance32 = 0; +static int COMPOBJ_Attach = 0; + +LPMALLOC currentMalloc32=NULL; + +WORD Table_ETask[62]; + +/* + * This lock count counts the number of times CoInitialize is called. It is + * decreased every time CoUninitialize is called. When it hits 0, the COM + * libraries are freed + */ +static ULONG s_COMLockCount = 0; + +/* + * This linked list contains the list of registered class objects. These + * are mostly used to register the factories for out-of-proc servers of OLE + * objects. + * + * TODO: Make this data structure aware of inter-process communication. This + * means that parts of this will be exported to the Wine Server. + */ +typedef struct tagRegisteredClass +{ + CLSID classIdentifier; + LPUNKNOWN classObject; + DWORD runContext; + DWORD connectFlags; + DWORD dwCookie; + struct tagRegisteredClass* nextClass; +} RegisteredClass; + +static RegisteredClass* firstRegisteredClass = NULL; + +/* this open DLL table belongs in a per process table, but my guess is that + * it shouldn't live in the kernel, so I'll put them out here in DLL + * space assuming that there is one OLE32 per process. + */ +typedef struct tagOpenDll { + HINSTANCE hLibrary; + struct tagOpenDll *next; +} OpenDll; + +static OpenDll *openDllList = NULL; /* linked list of open dlls */ + +/***************************************************************************** + * This section contains prototypes to internal methods for this + * module + */ +static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, + DWORD dwClsContext, + LPUNKNOWN* ppUnk); + +static void COM_RevokeAllClasses(); + + +/****************************************************************************** + * CoBuildVersion [COMPOBJ.1] + * + * RETURNS + * Current build version, hiword is majornumber, loword is minornumber + */ +DWORD WINAPI CoBuildVersion(void) +{ + Print(MAX_TRACE, ("Returning version %d, build %d.\n", 1, 0)); + return (1<<16)+0; +} + +/****************************************************************************** + * CoInitialize16 [COMPOBJ.2] + * Set the win16 IMalloc used for memory management + */ +HRESULT WINAPI CoInitialize16( + LPVOID lpReserved /* [in] pointer to win16 malloc interface */ +) { + UNIMPLEMENTED; + return S_OK; +} + +/****************************************************************************** + * CoInitialize [OLE32.26] + * + * Initializes the COM libraries. + * + * See CoInitializeEx + */ +HRESULT WINAPI CoInitialize( + LPVOID lpReserved /* [in] pointer to win32 malloc interface + (obsolete, should be NULL) */ +) +{ +#if 0 + /* + * Just delegate to the newer method. + */ + return CoInitializeEx(lpReserved, )COINIT_APARTMENTTHREADED); +#else + return E_FAIL; +#endif +} + +/****************************************************************************** + * CoInitializeEx [OLE32.163] + * + * Initializes the COM libraries. The behavior used to set the win32 IMalloc + * used for memory management is obsolete. + * + * RETURNS + * S_OK if successful, + * S_FALSE if this function was called already. + * RPC_E_CHANGED_MODE if a previous call to CoInitialize specified another + * threading model. + * + * BUGS + * Only the single threaded model is supported. As a result RPC_E_CHANGED_MODE + * is never returned. + * + * See the windows documentation for more details. + */ +HRESULT WINAPI CoInitializeEx( + LPVOID lpReserved, /* [in] pointer to win32 malloc interface + (obsolete, should be NULL) */ + DWORD dwCoInit /* [in] A value from COINIT specifies the threading model */ +) +{ + HRESULT hr; + + Print(MAX_TRACE, ("(%p, %x)\n", lpReserved, (int)dwCoInit)); + + if (lpReserved!=NULL) + { + Print(MIN_TRACE, ("(%p, %x) - Bad parameter passed-in %p, must be an old Windows Application\n", lpReserved, (int)dwCoInit, lpReserved)); + } + + /* + * Check for unsupported features. + */ + if (dwCoInit!=COINIT_APARTMENTTHREADED) + { + Print(MAX_TRACE, (":(%p,%x): unsupported flag %x\n", lpReserved, (int)dwCoInit, (int)dwCoInit)); + /* Hope for the best and continue anyway */ + } + + /* + * Check the lock count. If this is the first time going through the initialize + * process, we have to initialize the libraries. + */ + if (s_COMLockCount==0) + { + /* + * Initialize the various COM libraries and data structures. + */ + Print(MAX_TRACE, ("() - Initializing the COM libraries\n")); + + RunningObjectTableImpl_Initialize(); + + hr = S_OK; + } + else + hr = S_FALSE; + + /* + * Crank-up that lock count. + */ + s_COMLockCount++; + + return hr; +} + +/*********************************************************************** + * CoUninitialize16 [COMPOBJ.3] + * Don't know what it does. + * 3-Nov-98 -- this was originally misspelled, I changed it to what I + * believe is the correct spelling + */ +void WINAPI CoUninitialize16(void) +{ + Print(MAX_TRACE, ("Called\n")); + CoFreeAllLibraries(); +} + +/*********************************************************************** + * CoUninitialize [OLE32.47] + * + * This method will release the COM libraries. + * + * See the windows documentation for more details. + */ +void WINAPI CoUninitialize(void) +{ + Print(MAX_TRACE, ("Called\n")); + + /* + * Decrease the reference count. + */ + s_COMLockCount--; + + /* + * If we are back to 0 locks on the COM library, make sure we free + * all the associated data structures. + */ + if (s_COMLockCount==0) + { + /* + * Release the various COM libraries and data structures. + */ + Print(MAX_TRACE, ("() - Releasing the COM libraries\n")); + + RunningObjectTableImpl_UnInitialize(); + /* + * Release the references to the registered class objects. + */ + COM_RevokeAllClasses(); + + /* + * This will free the loaded COM Dlls. + */ + CoFreeAllLibraries(); + + /* + * This will free list of external references to COM objects. + */ + COM_ExternalLockFreeList(); +} +} + +/*********************************************************************** + * CoGetMalloc16 [COMPOBJ.4] + * RETURNS + * The current win16 IMalloc + */ +HRESULT WINAPI CoGetMalloc16( + DWORD dwMemContext, /* [in] unknown */ + PVOID lpMalloc /* [out] current win16 malloc interface */ +) { + UNIMPLEMENTED; + return S_OK; +} + +/****************************************************************************** + * CoGetMalloc [OLE32.20] + * + * RETURNS + * The current win32 IMalloc + */ +HRESULT WINAPI CoGetMalloc( + DWORD dwMemContext, /* [in] unknown */ + LPMALLOC *lpMalloc /* [out] current win32 malloc interface */ +) { +#if 0 + if(!currentMalloc32) + currentMalloc32 = IMalloc_Constructor(); + *lpMalloc = currentMalloc32; + return S_OK; +#else + UNIMPLEMENTED; + return S_OK; +#endif +} + +/*********************************************************************** + * CoCreateStandardMalloc16 [COMPOBJ.71] + */ +HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext, + PVOID lpMalloc) +{ + UNIMPLEMENTED; + return S_OK; +} + +/****************************************************************************** + * CoDisconnectObject [COMPOBJ.15] + */ +HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved ) +{ + Print(MAX_TRACE, ("(%p, %lx)\n",lpUnk,reserved)); + return S_OK; +} + +/*********************************************************************** + * IsEqualGUID16 [COMPOBJ.18] + * + * Compares two Unique Identifiers. + * + * RETURNS + * TRUE if equal + */ +BOOL WINAPI IsEqualGUID16( + GUID* g1, /* [in] unique id 1 */ + GUID* g2 /* [in] unique id 2 */ +) { + return !memcmp( g1, g2, sizeof(GUID) ); +} + +/****************************************************************************** + * CLSIDFromString16 [COMPOBJ.20] + * Converts a unique identifier from its string representation into + * the GUID struct. + * + * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6] + * + * RETURNS + * the converted GUID + */ +HRESULT WINAPI CLSIDFromString16( + LPCOLESTR16 idstr, /* [in] string representation of guid */ + CLSID *id /* [out] GUID converted from string */ +) { + BYTE *s = (BYTE *) idstr; + BYTE *p; + int i; + BYTE table[256]; + + if (!s) + s = "{00000000-0000-0000-0000-000000000000}"; + else { /* validate the CLSID string */ + + if (strlen(s) != 38) + return CO_E_CLASSSTRING; + + if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}')) + return CO_E_CLASSSTRING; + + for (i=1; i<37; i++) + { + if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue; + if (!(((s[i] >= '0') && (s[i] <= '9')) || + ((s[i] >= 'a') && (s[i] <= 'f')) || + ((s[i] >= 'A') && (s[i] <= 'F'))) + ) + return CO_E_CLASSSTRING; + } + } + + Print(MAX_TRACE, ("%s -> %p\n", s, id)); + + /* quick lookup table */ + memset(table, 0, 256); + + for (i = 0; i < 10; i++) { + table['0' + i] = i; + } + for (i = 0; i < 6; i++) { + table['A' + i] = i+10; + table['a' + i] = i+10; + } + + /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */ + + p = (BYTE *) id; + + s++; /* skip leading brace */ + for (i = 0; i < 4; i++) { + p[3 - i] = table[*s]<<4 | table[*(s+1)]; + s += 2; + } + p += 4; + s++; /* skip - */ + + for (i = 0; i < 2; i++) { + p[1-i] = table[*s]<<4 | table[*(s+1)]; + s += 2; + } + p += 2; + s++; /* skip - */ + + for (i = 0; i < 2; i++) { + p[1-i] = table[*s]<<4 | table[*(s+1)]; + s += 2; + } + p += 2; + s++; /* skip - */ + + /* these are just sequential bytes */ + for (i = 0; i < 2; i++) { + *p++ = table[*s]<<4 | table[*(s+1)]; + s += 2; + } + s++; /* skip - */ + + for (i = 0; i < 6; i++) { + *p++ = table[*s]<<4 | table[*(s+1)]; + s += 2; + } + + return S_OK; +} + +/****************************************************************************** + * CoCreateGuid[OLE32.6] + * + */ +HRESULT WINAPI CoCreateGuid( + GUID *pguid /* [out] points to the GUID to initialize */ +) { + return UuidCreate(pguid); +} + +/****************************************************************************** + * CLSIDFromString [OLE32.3] + * Converts a unique identifier from its string representation into + * the GUID struct. + * + * UNDOCUMENTED + * If idstr is not a valid CLSID string then it gets treated as a ProgID + * + * RETURNS + * the converted GUID + */ +HRESULT WINAPI CLSIDFromString( + LPCOLESTR idstr, /* [in] string representation of GUID */ + CLSID *id /* [out] GUID represented by above string */ +) { +#if 0 + LPOLESTR16 xid = HEAP_strdupWtoA(GetProcessHeap(),0,idstr); + HRESULT ret = CLSIDFromString16(xid,id); + + HeapFree(GetProcessHeap(),0,xid); + if(ret != S_OK) { /* It appears a ProgID is also valid */ + ret = CLSIDFromProgID(idstr, id); + } + return ret; +#else + UNIMPLEMENTED; + return (HRESULT)0; +#endif +} + +/****************************************************************************** + * WINE_StringFromCLSID [Internal] + * Converts a GUID into the respective string representation. + * + * NOTES + * + * RETURNS + * the string representation and HRESULT + */ +static HRESULT WINE_StringFromCLSID( + const CLSID *id, /* [in] GUID to be converted */ + LPSTR idstr /* [out] pointer to buffer to contain converted guid */ +) { + static const char *hex = "0123456789ABCDEF"; + char *s; + int i; + + if (!id) + { Print(MIN_TRACE, ("called with id=Null\n")); + *idstr = 0x00; + return E_FAIL; + } + + sprintf(idstr, "{%08lX-%04X-%04X-%02X%02X-", + id->Data1, id->Data2, id->Data3, + id->Data4[0], id->Data4[1]); + s = &idstr[25]; + + /* 6 hex bytes */ + for (i = 2; i < 8; i++) { + *s++ = hex[id->Data4[i]>>4]; + *s++ = hex[id->Data4[i] & 0xf]; + } + + *s++ = '}'; + *s++ = '\0'; + + Print(MAX_TRACE, ("%p->%s\n", id, idstr)); + + return S_OK; +} + +/****************************************************************************** + * StringFromCLSID16 [COMPOBJ.19] + * Converts a GUID into the respective string representation. + * The target string is allocated using the OLE IMalloc. + * RETURNS + * the string representation and HRESULT + */ +HRESULT WINAPI StringFromCLSID16( + REFCLSID id, /* [in] the GUID to be converted */ + LPOLESTR16 *idstr /* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */ + +) { +#if 0 + extern BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags, + DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode ); + LPMALLOC16 mllc; + HRESULT ret; + DWORD args[2]; + + ret = CoGetMalloc16(0,&mllc); + if (ret) return ret; + + args[0] = (DWORD)mllc; + args[1] = 40; + + /* No need for a Callback entry, we have WOWCallback16Ex which does + * everything we need. + */ + if (!K32WOWCallback16Ex( + (DWORD)((ICOM_VTABLE(IMalloc16)*)MapSL( + (SEGPTR)ICOM_VTBL(((LPMALLOC16)MapSL((SEGPTR)mllc)))) + )->Alloc, + WCB16_CDECL, + 2*sizeof(DWORD), + (LPVOID)args, + (LPDWORD)idstr + )) { + WARN("CallTo16 IMalloc16 failed\n"); + return E_FAIL; + } + return WINE_StringFromCLSID(id,MapSL((SEGPTR)*idstr)); +#else + UNIMPLEMENTED; + return (HRESULT)0; +#endif +} + +/****************************************************************************** + * StringFromCLSID [OLE32.151] + * Converts a GUID into the respective string representation. + * The target string is allocated using the OLE IMalloc. + * RETURNS + * the string representation and HRESULT + */ +HRESULT WINAPI StringFromCLSID( + REFCLSID id, /* [in] the GUID to be converted */ + LPOLESTR *idstr /* [out] a pointer to a to-be-allocated pointer pointing to the resulting string */ +) { + char buf[80]; + HRESULT ret; + LPMALLOC mllc; + + if ((ret=CoGetMalloc(0,&mllc))) + return ret; + + ret=WINE_StringFromCLSID(id,buf); + if (!ret) { + DWORD len = MultiByteToWideChar( CP_ACP, 0, buf, -1, NULL, 0 ); + *idstr = IMalloc_Alloc( mllc, len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, buf, -1, *idstr, len ); + } + return ret; +} + +/****************************************************************************** + * StringFromGUID2 [COMPOBJ.76] [OLE32.152] + * + * Converts a global unique identifier into a string of an API- + * specified fixed format. (The usual {.....} stuff.) + * + * RETURNS + * The (UNICODE) string representation of the GUID in 'str' + * The length of the resulting string, 0 if there was any problem. + */ +INT WINAPI +StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax) +{ + char xguid[80]; + + if (WINE_StringFromCLSID(id,xguid)) + return 0; + return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax ); +} + +/****************************************************************************** + * ProgIDFromCLSID [OLE32.133] + * Converts a class id into the respective Program ID. (By using a registry lookup) + * RETURNS S_OK on success + * riid associated with the progid + */ + +HRESULT WINAPI ProgIDFromCLSID( + REFCLSID clsid, /* [in] class id as found in registry */ + LPOLESTR *lplpszProgID/* [out] associated Prog ID */ +) +{ + char strCLSID[50], *buf, *buf2; + DWORD buf2len; + HKEY xhkey; + LPMALLOC mllc; + HRESULT ret = S_OK; + + WINE_StringFromCLSID(clsid, strCLSID); + + buf = HeapAlloc(GetProcessHeap(), 0, strlen(strCLSID)+14); + sprintf(buf,"CLSID\\%s\\ProgID", strCLSID); + if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey)) + ret = REGDB_E_CLASSNOTREG; + + HeapFree(GetProcessHeap(), 0, buf); + + if (ret == S_OK) + { + buf2 = HeapAlloc(GetProcessHeap(), 0, 255); + buf2len = 255; + if (RegQueryValueA(xhkey, NULL, buf2, &buf2len)) + ret = REGDB_E_CLASSNOTREG; + + if (ret == S_OK) + { + if (CoGetMalloc(0,&mllc)) + ret = E_OUTOFMEMORY; + else + { + DWORD len = MultiByteToWideChar( CP_ACP, 0, buf2, -1, NULL, 0 ); + *lplpszProgID = IMalloc_Alloc(mllc, len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, buf2, -1, *lplpszProgID, len ); + } + } + HeapFree(GetProcessHeap(), 0, buf2); + } + + RegCloseKey(xhkey); + return ret; +} + +/****************************************************************************** + * CLSIDFromProgID16 [COMPOBJ.61] + * Converts a program id into the respective GUID. (By using a registry lookup) + * RETURNS + * riid associated with the progid + */ +HRESULT WINAPI CLSIDFromProgID16( + LPCOLESTR16 progid, /* [in] program id as found in registry */ + LPCLSID riid /* [out] associated CLSID */ +) { + char *buf,buf2[80]; + DWORD buf2len; + HRESULT err; + HKEY xhkey; + + buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8); + sprintf(buf,"%s\\CLSID",progid); + if ((err=RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey))) { + HeapFree(GetProcessHeap(),0,buf); + return CO_E_CLASSSTRING; + } + HeapFree(GetProcessHeap(),0,buf); + buf2len = sizeof(buf2); + if ((err=RegQueryValueA(xhkey,NULL,buf2,&buf2len))) { + RegCloseKey(xhkey); + return CO_E_CLASSSTRING; + } + RegCloseKey(xhkey); + return CLSIDFromString16(buf2,riid); +} + +/****************************************************************************** + * CLSIDFromProgID [OLE32.2] + * Converts a program id into the respective GUID. (By using a registry lookup) + * RETURNS + * riid associated with the progid + */ +HRESULT WINAPI CLSIDFromProgID( + LPCOLESTR progid, /* [in] program id as found in registry */ + LPCLSID riid /* [out] associated CLSID */ +) { +#if 0 + LPOLESTR16 pid = HEAP_strdupWtoA(GetProcessHeap(),0,progid); + HRESULT ret = CLSIDFromProgID16(pid,riid); + + HeapFree(GetProcessHeap(),0,pid); + return ret; +#else + UNIMPLEMENTED; + return (HRESULT)0; +#endif +} + + + +/***************************************************************************** + * CoGetPSClsid [OLE32.22] + * + * This function returns the CLSID of the DLL that implements the proxy and stub + * for the specified interface. + * + * It determines this by searching the + * HKEY_CLASSES_ROOT\Interface\{string form of riid}\ProxyStubClsid32 in the registry + * and any interface id registered by CoRegisterPSClsid within the current process. + * + * FIXME: We only search the registry, not ids registered with CoRegisterPSClsid. + */ +HRESULT WINAPI CoGetPSClsid( + REFIID riid, /* [in] Interface whose proxy/stub CLSID is to be returned */ + CLSID *pclsid ) /* [out] Where to store returned proxy/stub CLSID */ +{ + char *buf, buf2[40]; + DWORD buf2len; + HKEY xhkey; + + Print(MAX_TRACE, ("() riid=%s, pclsid=%p\n", PRINT_GUID(riid), pclsid)); + + /* Get the input iid as a string */ + WINE_StringFromCLSID(riid, buf2); + /* Allocate memory for the registry key we will construct. + (length of iid string plus constant length of static text */ + buf = HeapAlloc(GetProcessHeap(), 0, strlen(buf2)+27); + if (buf == NULL) + { + return (E_OUTOFMEMORY); + } + + /* Construct the registry key we want */ + sprintf(buf,"Interface\\%s\\ProxyStubClsid32", buf2); + + /* Open the key.. */ + if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey)) + { + HeapFree(GetProcessHeap(),0,buf); + return (E_INVALIDARG); + } + HeapFree(GetProcessHeap(),0,buf); + + /* ... Once we have the key, query the registry to get the + value of CLSID as a string, and convert it into a + proper CLSID structure to be passed back to the app */ + buf2len = sizeof(buf2); + if ( (RegQueryValueA(xhkey,NULL,buf2,&buf2len)) ) + { + RegCloseKey(xhkey); + return E_INVALIDARG; + } + RegCloseKey(xhkey); + + /* We have the CLSid we want back from the registry as a string, so + lets convert it into a CLSID structure */ + if ( (CLSIDFromString16(buf2,pclsid)) != NOERROR) + { + return E_INVALIDARG; + } + + Print(MAX_TRACE, ("() Returning CLSID=%s\n", PRINT_GUID(pclsid))); + return (S_OK); +} + + + +/*********************************************************************** + * WriteClassStm + * + * This function write a CLSID on stream + */ +HRESULT WINAPI WriteClassStm(IStream *pStm,REFCLSID rclsid) +{ + Print(MAX_TRACE, ("(%p,%p)\n",pStm,rclsid)); + + if (rclsid==NULL) + return E_INVALIDARG; + + return IStream_Write(pStm,rclsid,sizeof(CLSID),NULL); +} + +/*********************************************************************** + * ReadClassStm + * + * This function read a CLSID from a stream + */ +HRESULT WINAPI ReadClassStm(IStream *pStm,REFCLSID rclsid) +{ + ULONG nbByte; + HRESULT res; + + Print(MAX_TRACE, ("(%p,%p)\n",pStm,rclsid)); + + if (rclsid==NULL) + return E_INVALIDARG; + + res = IStream_Read(pStm,(void*)rclsid,sizeof(CLSID),&nbByte); + + if (FAILED(res)) + return res; + + if (nbByte != sizeof(CLSID)) + return S_FALSE; + else + return S_OK; +} + +/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */ +/*********************************************************************** + * LookupETask (COMPOBJ.94) + */ +HRESULT WINAPI LookupETask16(PVOID hTask,LPVOID p) { + UNIMPLEMENTED; + return S_OK; +} + +/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */ +/*********************************************************************** + * SetETask (COMPOBJ.95) + */ +HRESULT WINAPI SetETask16(DWORD hTask, LPVOID p) { + UNIMPLEMENTED; + return S_OK; +} + +/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */ +/*********************************************************************** + * CallObjectInWOW (COMPOBJ.201) + */ +HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) { + UNIMPLEMENTED; + return 0; +} + +/****************************************************************************** + * CoRegisterClassObject16 [COMPOBJ.5] + * + * Don't know where it registers it ... + */ +HRESULT WINAPI CoRegisterClassObject16( + REFCLSID rclsid, + LPUNKNOWN pUnk, + DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */ + DWORD flags, /* [in] REGCLS flags indicating how connections are made */ + LPDWORD lpdwRegister +) { + UNIMPLEMENTED; + return S_OK; +} + + +/****************************************************************************** + * CoRevokeClassObject16 [COMPOBJ.6] + * + */ +HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */ +{ + UNIMPLEMENTED; + return S_OK; +} + + +/*** + * COM_GetRegisteredClassObject + * + * This internal method is used to scan the registered class list to + * find a class object. + * + * Params: + * rclsid Class ID of the class to find. + * dwClsContext Class context to match. + * ppv [out] returns a pointer to the class object. Complying + * to normal COM usage, this method will increase the + * reference count on this object. + */ +static HRESULT COM_GetRegisteredClassObject( + REFCLSID rclsid, + DWORD dwClsContext, + LPUNKNOWN* ppUnk) +{ + RegisteredClass* curClass; + + /* + * Sanity check + */ + assert(ppUnk!=0); + + /* + * Iterate through the whole list and try to match the class ID. + */ + curClass = firstRegisteredClass; + + while (curClass != 0) + { + /* + * Check if we have a match on the class ID. + */ + if (IsEqualGUID(&(curClass->classIdentifier), rclsid)) + { + /* + * Since we don't do out-of process or DCOM just right away, let's ignore the + * class context. + */ + + /* + * We have a match, return the pointer to the class object. + */ + *ppUnk = curClass->classObject; + + IUnknown_AddRef(curClass->classObject); + + return S_OK; + } + + /* + * Step to the next class in the list. + */ + curClass = curClass->nextClass; + } + + /* + * If we get to here, we haven't found our class. + */ + return S_FALSE; +} + +/****************************************************************************** + * CoRegisterClassObject [OLE32.36] + * + * This method will register the class object for a given class ID. + * + * See the Windows documentation for more details. + */ +HRESULT WINAPI CoRegisterClassObject( + REFCLSID rclsid, + LPUNKNOWN pUnk, + DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */ + DWORD flags, /* [in] REGCLS flags indicating how connections are made */ + LPDWORD lpdwRegister +) +{ + RegisteredClass* newClass; + LPUNKNOWN foundObject; + HRESULT hr; + char buf[80]; + + WINE_StringFromCLSID(rclsid,buf); + + Print(MAX_TRACE, ("(%s,%p,0x%08lx,0x%08lx,%p)\n", + buf,pUnk,dwClsContext,flags,lpdwRegister)); + + /* + * Perform a sanity check on the parameters + */ + if ( (lpdwRegister==0) || (pUnk==0) ) + { + return E_INVALIDARG; +} + + /* + * Initialize the cookie (out parameter) + */ + *lpdwRegister = 0; + + /* + * First, check if the class is already registered. + * If it is, this should cause an error. + */ + hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject); + + if (hr == S_OK) + { + /* + * The COM_GetRegisteredClassObject increased the reference count on the + * object so it has to be released. + */ + IUnknown_Release(foundObject); + + return CO_E_OBJISREG; + } + + /* + * If it is not registered, we must create a new entry for this class and + * append it to the registered class list. + * We use the address of the chain node as the cookie since we are sure it's + * unique. + */ + newClass = HeapAlloc(GetProcessHeap(), 0, sizeof(RegisteredClass)); + + /* + * Initialize the node. + */ + newClass->classIdentifier = *rclsid; + newClass->runContext = dwClsContext; + newClass->connectFlags = flags; + newClass->dwCookie = (DWORD)newClass; + newClass->nextClass = firstRegisteredClass; + + /* + * Since we're making a copy of the object pointer, we have to increase its + * reference count. + */ + newClass->classObject = pUnk; + IUnknown_AddRef(newClass->classObject); + + firstRegisteredClass = newClass; + + /* + * Assign the out parameter (cookie) + */ + *lpdwRegister = newClass->dwCookie; + + /* + * We're successful Yippee! + */ + return S_OK; +} + +/*********************************************************************** + * CoRevokeClassObject [OLE32.40] + * + * This method will remove a class object from the class registry + * + * See the Windows documentation for more details. + */ +HRESULT WINAPI CoRevokeClassObject( + DWORD dwRegister) +{ + RegisteredClass** prevClassLink; + RegisteredClass* curClass; + + Print(MAX_TRACE, ("(%08lx)\n",dwRegister)); + + /* + * Iterate through the whole list and try to match the cookie. + */ + curClass = firstRegisteredClass; + prevClassLink = &firstRegisteredClass; + + while (curClass != 0) + { + /* + * Check if we have a match on the cookie. + */ + if (curClass->dwCookie == dwRegister) + { + /* + * Remove the class from the chain. + */ + *prevClassLink = curClass->nextClass; + + /* + * Release the reference to the class object. + */ + IUnknown_Release(curClass->classObject); + + /* + * Free the memory used by the chain node. + */ + HeapFree(GetProcessHeap(), 0, curClass); + + return S_OK; +} + + /* + * Step to the next class in the list. + */ + prevClassLink = &(curClass->nextClass); + curClass = curClass->nextClass; + } + + /* + * If we get to here, we haven't found our class. + */ + return E_INVALIDARG; +} + +/*********************************************************************** + * CoGetClassObject [COMPOBJ.7] + */ +HRESULT WINAPI CoGetClassObject( + REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, + REFIID iid, LPVOID *ppv +) { + LPUNKNOWN regClassObject; + HRESULT hres = E_UNEXPECTED; + char xclsid[80]; + WCHAR dllName[MAX_PATH+1]; + DWORD dllNameLen = sizeof(dllName); + HINSTANCE hLibrary; + typedef HRESULT CALLBACK (*DllGetClassObjectFunc)(REFCLSID clsid, + REFIID iid, LPVOID *ppv); + DllGetClassObjectFunc DllGetClassObject; + + WINE_StringFromCLSID((LPCLSID)rclsid,xclsid); + + Print(MIN_TRACE, ("\n\tCLSID:\t%s,\n\tIID:\t%s\n", + PRINT_GUID(rclsid), + PRINT_GUID(iid) + )); + + if (pServerInfo) { + Print(MIN_TRACE, ("\tpServerInfo: name=%S\n",pServerInfo->pwszName)); + Print(MIN_TRACE, ("\t\tpAuthInfo=%p\n",pServerInfo->pAuthInfo)); + } + + /* + * First, try and see if we can't match the class ID with one of the + * registered classes. + */ + if (S_OK == COM_GetRegisteredClassObject(rclsid, dwClsContext, ®ClassObject)) + { + /* + * Get the required interface from the retrieved pointer. + */ + hres = IUnknown_QueryInterface(regClassObject, iid, ppv); + + /* + * Since QI got another reference on the pointer, we want to release the + * one we already have. If QI was unsuccessful, this will release the object. This + * is good since we are not returning it in the "out" parameter. + */ + IUnknown_Release(regClassObject); + + return hres; + } + + /* out of process and remote servers not supported yet */ + if ( ((CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER) & dwClsContext) + && !((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext) + ){ + Print(MIN_TRACE, ("%s %s not supported!\n", + (dwClsContext&CLSCTX_LOCAL_SERVER)?"CLSCTX_LOCAL_SERVER":"", + (dwClsContext&CLSCTX_REMOTE_SERVER)?"CLSCTX_REMOTE_SERVER":"" + )); + return E_ACCESSDENIED; + } + + if ((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext) { + HKEY key; + char buf[200]; + + sprintf(buf,"CLSID\\%s\\InprocServer32",xclsid); + hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key); + + if (hres != ERROR_SUCCESS) { + return REGDB_E_CLASSNOTREG; + } + + memset(dllName,0,sizeof(dllName)); + hres= RegQueryValueExW(key,NULL,NULL,NULL,(LPBYTE)dllName,&dllNameLen); + if (hres) + return REGDB_E_CLASSNOTREG; /* FIXME: check retval */ + RegCloseKey(key); + Print(MAX_TRACE, ("found InprocServer32 dll %S\n", dllName)); + + /* open dll, call DllGetClassObject */ + hLibrary = CoLoadLibrary(dllName, TRUE); + if (hLibrary == 0) { + Print(MIN_TRACE, ("couldn't load InprocServer32 dll %S\n", dllName)); + return E_ACCESSDENIED; /* or should this be CO_E_DLLNOTFOUND? */ + } + DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"); + if (!DllGetClassObject) { + /* not sure if this should be called here CoFreeLibrary(hLibrary);*/ + Print(MIN_TRACE, ("couldn't find function DllGetClassObject in %S\n", dllName)); + return E_ACCESSDENIED; + } + + /* + * Ask the DLL for its class object. (there was a note here about class + * factories but this is good. + */ + return DllGetClassObject(rclsid, iid, ppv); + } + return hres; +} + +/*********************************************************************** + * CoResumeClassObjects + * + * Resumes classobjects registered with REGCLS suspended + */ +HRESULT WINAPI CoResumeClassObjects(void) +{ + UNIMPLEMENTED; + return S_OK; +} + +/*********************************************************************** + * GetClassFile + * + * This function supplies the CLSID associated with the given filename. + */ +HRESULT WINAPI GetClassFile(LPOLESTR filePathName,CLSID *pclsid) +{ + IStorage *pstg=0; + HRESULT res; + int nbElm=0,length=0,i=0; + LONG sizeProgId=20; + LPOLESTR *pathDec=0,absFile=0,progId=0; + WCHAR extention[100]={0}; + + Print(MAX_TRACE, ("()\n")); + + /* if the file contain a storage object the return the CLSID writen by IStorage_SetClass method*/ + if((StgIsStorageFile(filePathName))==S_OK){ + + res=StgOpenStorage(filePathName,NULL,STGM_READ | STGM_SHARE_DENY_WRITE,NULL,0,&pstg); + + if (SUCCEEDED(res)) + res=ReadClassStg(pstg,pclsid); + + IStorage_Release(pstg); + + return res; + } + /* if the file is not a storage object then attemps to match various bits in the file against a + pattern in the registry. this case is not frequently used ! so I present only the psodocode for + this case + + for(i=0;i=0) && (extention[i]=absFile[i]) );i--); + + /* get the progId associated to the extension */ + progId=CoTaskMemAlloc(sizeProgId); + + res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId); + + if (res==ERROR_MORE_DATA){ + + progId = CoTaskMemRealloc(progId,sizeProgId); + res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId); + } + if (res==ERROR_SUCCESS) + /* return the clsid associated to the progId */ + res= CLSIDFromProgID(progId,pclsid); + + for(i=0; pathDec[i]!=NULL;i++) + CoTaskMemFree(pathDec[i]); + CoTaskMemFree(pathDec); + + CoTaskMemFree(progId); + + if (res==ERROR_SUCCESS) + return res; + + return MK_E_INVALIDEXTENSION; +} +/****************************************************************************** + * CoRegisterMessageFilter16 [COMPOBJ.27] + */ +HRESULT WINAPI CoRegisterMessageFilter16( + DWORD lpMessageFilter, + DWORD *lplpMessageFilter +) { + UNIMPLEMENTED; + return 0; +} + +/*********************************************************************** + * CoCreateInstance [COMPOBJ.13, OLE32.7] + */ +HRESULT WINAPI CoCreateInstance( + REFCLSID rclsid, + LPUNKNOWN pUnkOuter, + DWORD dwClsContext, + REFIID iid, + LPVOID *ppv) +{ + HRESULT hres; + LPCLASSFACTORY lpclf = 0; + + /* + * Sanity check + */ + if (ppv==0) + return E_POINTER; + + /* + * Initialize the "out" parameter + */ + *ppv = 0; + + /* + * Get a class factory to construct the object we want. + */ + hres = CoGetClassObject(rclsid, + dwClsContext, + NULL, + &IID_IClassFactory, + (LPVOID)&lpclf); + + if (FAILED(hres)) { + Print(MIN_TRACE, ("no instance created for %s, hres is 0x%08lx\n",PRINT_GUID(iid),hres)); + return hres; + } + + /* + * Create the object and don't forget to release the factory + */ + hres = IClassFactory_CreateInstance(lpclf, pUnkOuter, iid, ppv); + IClassFactory_Release(lpclf); + + return hres; +} + +/*********************************************************************** + * CoCreateInstanceEx [OLE32.165] + */ +HRESULT WINAPI CoCreateInstanceEx( + REFCLSID rclsid, + LPUNKNOWN pUnkOuter, + DWORD dwClsContext, + COSERVERINFO* pServerInfo, + ULONG cmq, + MULTI_QI* pResults) +{ + IUnknown* pUnk = NULL; + HRESULT hr; + ULONG index; + int successCount = 0; + + /* + * Sanity check + */ + if ( (cmq==0) || (pResults==NULL)) + return E_INVALIDARG; + + if (pServerInfo!=NULL) + Print(MIN_TRACE, ("() non-NULL pServerInfo not supported!\n")); + + /* + * Initialize all the "out" parameters. + */ + for (index = 0; index < cmq; index++) + { + pResults[index].pItf = NULL; + pResults[index].hr = E_NOINTERFACE; + } + + /* + * Get the object and get its IUnknown pointer. + */ + hr = CoCreateInstance(rclsid, + pUnkOuter, + dwClsContext, + &IID_IUnknown, + (VOID**)&pUnk); + + if (hr) + return hr; + + /* + * Then, query for all the interfaces requested. + */ + for (index = 0; index < cmq; index++) + { + pResults[index].hr = IUnknown_QueryInterface(pUnk, + pResults[index].pIID, + (VOID**)&(pResults[index].pItf)); + + if (pResults[index].hr == S_OK) + successCount++; + } + + /* + * Release our temporary unknown pointer. + */ + IUnknown_Release(pUnk); + + if (successCount == 0) + return E_NOINTERFACE; + + if (successCount!=cmq) + return CO_S_NOTALLINTERFACES; + + return S_OK; +} + +/*********************************************************************** + * CoFreeLibrary [COMPOBJ.13] + */ +void WINAPI CoFreeLibrary(HINSTANCE hLibrary) +{ + OpenDll *ptr, *prev; + OpenDll *tmp; + + /* lookup library in linked list */ + prev = NULL; + for (ptr = openDllList; ptr != NULL; ptr=ptr->next) { + if (ptr->hLibrary == hLibrary) { + break; + } + prev = ptr; + } + + if (ptr == NULL) { + /* shouldn't happen if user passed in a valid hLibrary */ + return; + } + /* assert: ptr points to the library entry to free */ + + /* free library and remove node from list */ + FreeLibrary(hLibrary); + if (ptr == openDllList) { + tmp = openDllList->next; + HeapFree(GetProcessHeap(), 0, openDllList); + openDllList = tmp; + } else { + tmp = ptr->next; + HeapFree(GetProcessHeap(), 0, ptr); + prev->next = tmp; + } + +} + + +/*********************************************************************** + * CoFreeAllLibraries [COMPOBJ.12] + */ +void WINAPI CoFreeAllLibraries(void) +{ + OpenDll *ptr, *tmp; + + for (ptr = openDllList; ptr != NULL; ) { + tmp=ptr->next; + CoFreeLibrary(ptr->hLibrary); + ptr = tmp; + } +} + + + +/*********************************************************************** + * CoFreeUnusedLibraries [COMPOBJ.17] + */ +void WINAPI CoFreeUnusedLibraries(void) +{ + OpenDll *ptr, *tmp; + typedef HRESULT(*DllCanUnloadNowFunc)(void); + DllCanUnloadNowFunc DllCanUnloadNow; + + for (ptr = openDllList; ptr != NULL; ) { + DllCanUnloadNow = (DllCanUnloadNowFunc) + GetProcAddress(ptr->hLibrary, "DllCanUnloadNow"); + + if ( (DllCanUnloadNow != NULL) && + (DllCanUnloadNow() == S_OK) ) { + tmp=ptr->next; + CoFreeLibrary(ptr->hLibrary); + ptr = tmp; + } else { + ptr=ptr->next; + } + } +} + +/*********************************************************************** + * CoFileTimeNow [COMPOBJ.82, OLE32.10] + * RETURNS + * the current system time in lpFileTime + */ +HRESULT WINAPI CoFileTimeNow( FILETIME *lpFileTime ) /* [out] the current time */ +{ + GetSystemTimeAsFileTime( lpFileTime ); + return S_OK; +} + +/*********************************************************************** + * CoTaskMemAlloc (OLE32.43) + * RETURNS + * pointer to newly allocated block + */ +LPVOID WINAPI CoTaskMemAlloc( + ULONG size /* [in] size of memoryblock to be allocated */ +) { + LPMALLOC lpmalloc; + HRESULT ret = CoGetMalloc(0,&lpmalloc); + + if (FAILED(ret)) + return NULL; + + return IMalloc_Alloc(lpmalloc,size); +} +/*********************************************************************** + * CoTaskMemFree (OLE32.44) + */ +VOID WINAPI CoTaskMemFree( + LPVOID ptr /* [in] pointer to be freed */ +) { + LPMALLOC lpmalloc; + HRESULT ret = CoGetMalloc(0,&lpmalloc); + + if (FAILED(ret)) + return; + + IMalloc_Free(lpmalloc, ptr); +} + +/*********************************************************************** + * CoTaskMemRealloc (OLE32.45) + * RETURNS + * pointer to newly allocated block + */ +LPVOID WINAPI CoTaskMemRealloc( + LPVOID pvOld, + ULONG size) /* [in] size of memoryblock to be allocated */ +{ + LPMALLOC lpmalloc; + HRESULT ret = CoGetMalloc(0,&lpmalloc); + + if (FAILED(ret)) + return NULL; + + return IMalloc_Realloc(lpmalloc, pvOld, size); +} + +/*********************************************************************** + * CoLoadLibrary (OLE32.30) + */ +HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree) +{ + HINSTANCE hLibrary; + OpenDll *ptr; + OpenDll *tmp; + + Print(MAX_TRACE, ("(%S, %d)\n", lpszLibName, bAutoFree)); + + hLibrary = LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + + if (!bAutoFree) + return hLibrary; + + if (openDllList == NULL) { + /* empty list -- add first node */ + openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll)); + openDllList->hLibrary=hLibrary; + openDllList->next = NULL; + } else { + /* search for this dll */ + int found = FALSE; + for (ptr = openDllList; ptr->next != NULL; ptr=ptr->next) { + if (ptr->hLibrary == hLibrary) { + found = TRUE; + break; + } + } + if (!found) { + /* dll not found, add it */ + tmp = openDllList; + openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll)); + openDllList->hLibrary = hLibrary; + openDllList->next = tmp; + } + } + + return hLibrary; +} + +/*********************************************************************** + * CoInitializeWOW (OLE32.27) + */ +HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) { + UNIMPLEMENTED; + return 0; +} + +/****************************************************************************** + * CoLockObjectExternal16 [COMPOBJ.63] + */ +HRESULT WINAPI CoLockObjectExternal16( + LPUNKNOWN pUnk, /* [in] object to be locked */ + BOOL fLock, /* [in] do lock */ + BOOL fLastUnlockReleases /* [in] ? */ +) { + UNIMPLEMENTED; + return S_OK; +} + +/****************************************************************************** + * CoLockObjectExternal [OLE32.31] + */ +HRESULT WINAPI CoLockObjectExternal( + LPUNKNOWN pUnk, /* [in] object to be locked */ + BOOL fLock, /* [in] do lock */ + BOOL fLastUnlockReleases) /* [in] unlock all */ +{ + + if (fLock) + { + /* + * Increment the external lock coutner, COM_ExternalLockAddRef also + * increment the object's internal lock counter. + */ + COM_ExternalLockAddRef( pUnk); + } + else + { + /* + * Decrement the external lock coutner, COM_ExternalLockRelease also + * decrement the object's internal lock counter. + */ + COM_ExternalLockRelease( pUnk, fLastUnlockReleases); + } + + return S_OK; +} + +/*********************************************************************** + * CoGetState16 [COMPOBJ.115] + */ +HRESULT WINAPI CoGetState16(LPDWORD state) +{ + UNIMPLEMENTED + return S_OK; +} +/*********************************************************************** + * CoSetState [COM32.42] + */ +HRESULT WINAPI CoSetState(LPDWORD state) +{ + UNIMPLEMENTED; + return S_OK; +} +/*********************************************************************** + * CoCreateFreeThreadedMarshaler [OLE32.5] + */ +HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN* ppunkMarshal) +{ + UNIMPLEMENTED; + return S_OK; +} + + +/*********************************************************************** + * DllGetClassObject [OLE32.63] + */ +HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) +{ + UNIMPLEMENTED; + *ppv = NULL; + return CLASS_E_CLASSNOTAVAILABLE; +} + + +/*** + * COM_RevokeAllClasses + * + * This method is called when the COM libraries are uninitialized to + * release all the references to the class objects registered with + * the library + */ +static void COM_RevokeAllClasses() +{ + while (firstRegisteredClass!=0) + { + CoRevokeClassObject(firstRegisteredClass->dwCookie); + } +} + +/**************************************************************************** + * COM External Lock methods implementation + */ + +/**************************************************************************** + * Public - Method that increments the count for a IUnknown* in the linked + * list. The item is inserted if not already in the list. + */ +static void COM_ExternalLockAddRef( + IUnknown *pUnk) +{ + COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk); + + /* + * Add an external lock to the object. If it was already externally + * locked, just increase the reference count. If it was not. + * add the item to the list. + */ + if ( externalLock == EL_NOT_FOUND ) + COM_ExternalLockInsert(pUnk); + else + externalLock->uRefCount++; + + /* + * Add an internal lock to the object + */ + IUnknown_AddRef(pUnk); +} + +/**************************************************************************** + * Public - Method that decrements the count for a IUnknown* in the linked + * list. The item is removed from the list if its count end up at zero or if + * bRelAll is TRUE. + */ +static void COM_ExternalLockRelease( + IUnknown *pUnk, + BOOL bRelAll) +{ + COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk); + + if ( externalLock != EL_NOT_FOUND ) + { + do + { + externalLock->uRefCount--; /* release external locks */ + IUnknown_Release(pUnk); /* release local locks as well */ + + if ( bRelAll == FALSE ) + break; /* perform single release */ + + } while ( externalLock->uRefCount > 0 ); + + if ( externalLock->uRefCount == 0 ) /* get rid of the list entry */ + COM_ExternalLockDelete(externalLock); + } +} +/**************************************************************************** + * Public - Method that frees the content of the list. + */ +static void COM_ExternalLockFreeList() +{ + COM_ExternalLock *head; + + head = elList.head; /* grab it by the head */ + while ( head != EL_END_OF_LIST ) + { + COM_ExternalLockDelete(head); /* get rid of the head stuff */ + + head = elList.head; /* get the new head... */ + } +} + +/**************************************************************************** + * Public - Method that dump the content of the list. + */ +void COM_ExternalLockDump() +{ + COM_ExternalLock *current = elList.head; + + Print(MAX_TRACE, ("\nExternal lock list contains:\n")); + + while ( current != EL_END_OF_LIST ) + { + Print(MAX_TRACE, ("\t%p with %lu references count.\n", current->pUnk, current->uRefCount)); + + /* Skip to the next item */ + current = current->next; + } + +} + +/**************************************************************************** + * Internal - Find a IUnknown* in the linked list + */ +static COM_ExternalLock* COM_ExternalLockFind( + IUnknown *pUnk) +{ + return COM_ExternalLockLocate(elList.head, pUnk); +} + +/**************************************************************************** + * Internal - Recursivity agent for IUnknownExternalLockList_Find + */ +static COM_ExternalLock* COM_ExternalLockLocate( + COM_ExternalLock *element, + IUnknown *pUnk) +{ + if ( element == EL_END_OF_LIST ) + return EL_NOT_FOUND; + + else if ( element->pUnk == pUnk ) /* We found it */ + return element; + + else /* Not the right guy, keep on looking */ + return COM_ExternalLockLocate( element->next, pUnk); +} + +/**************************************************************************** + * Internal - Insert a new IUnknown* to the linked list + */ +static BOOL COM_ExternalLockInsert( + IUnknown *pUnk) +{ + COM_ExternalLock *newLock = NULL; + COM_ExternalLock *previousHead = NULL; + + /* + * Allocate space for the new storage object + */ + newLock = HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock)); + + if (newLock!=NULL) + { + if ( elList.head == EL_END_OF_LIST ) + { + elList.head = newLock; /* The list is empty */ + } + else + { + /* + * insert does it at the head + */ + previousHead = elList.head; + elList.head = newLock; + } + + /* + * Set new list item data member + */ + newLock->pUnk = pUnk; + newLock->uRefCount = 1; + newLock->next = previousHead; + + return TRUE; + } + else + return FALSE; +} + +/**************************************************************************** + * Internal - Method that removes an item from the linked list. + */ +static void COM_ExternalLockDelete( + COM_ExternalLock *itemList) +{ + COM_ExternalLock *current = elList.head; + + if ( current == itemList ) + { + /* + * this section handles the deletion of the first node + */ + elList.head = itemList->next; + HeapFree( GetProcessHeap(), 0, itemList); + } + else + { + do + { + if ( current->next == itemList ) /* We found the item to free */ + { + current->next = itemList->next; /* readjust the list pointers */ + + HeapFree( GetProcessHeap(), 0, itemList); + break; + } + + /* Skip to the next item */ + current = current->next; + + } while ( current != EL_END_OF_LIST ); + } +} + +/*********************************************************************** + * COMPOBJ_DllEntryPoint [COMPOBJ.entry] + * + * Initialization code for the COMPOBJ DLL + * + * RETURNS: + */ +BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, DWORD hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2) +{ + Print(MAX_TRACE, ("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize, + res1, res2)); + switch(Reason) + { + case DLL_PROCESS_ATTACH: +#if 0 + if (!COMPOBJ_Attach++) COMPOBJ_hInstance = hInst; +#endif + break; + + case DLL_PROCESS_DETACH: +#if 0 + if(!--COMPOBJ_Attach) + COMPOBJ_hInstance = 0; +#endif + break; + } + return TRUE; +} + +/****************************************************************************** + * OleGetAutoConvert [OLE32.104] + */ +HRESULT WINAPI OleGetAutoConvert(REFCLSID clsidOld, LPCLSID pClsidNew) +{ + HKEY hkey = 0; + char buf[200]; + WCHAR wbuf[200]; + DWORD len; + HRESULT res = S_OK; + + sprintf(buf,"CLSID\\");WINE_StringFromCLSID(clsidOld,&buf[6]); + if (RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&hkey)) + { + res = REGDB_E_CLASSNOTREG; + goto done; + } + len = 200; + /* we can just query for the default value of AutoConvertTo key like that, + without opening the AutoConvertTo key and querying for NULL (default) */ + if (RegQueryValueA(hkey,"AutoConvertTo",buf,&len)) + { + res = REGDB_E_KEYMISSING; + goto done; + } + MultiByteToWideChar( CP_ACP, 0, buf, -1, wbuf, sizeof(wbuf)/sizeof(WCHAR) ); + CLSIDFromString(wbuf,pClsidNew); +done: + if (hkey) RegCloseKey(hkey); + + return res; +} + +/****************************************************************************** + * OleSetAutoConvert [OLE32.126] + */ +HRESULT WINAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew) +{ + HKEY hkey = 0, hkeyConvert = 0; + char buf[200], szClsidNew[200]; + HRESULT res = S_OK; + + Print(MAX_TRACE, ("(%p,%p);\n", clsidOld, clsidNew)); + sprintf(buf,"CLSID\\");WINE_StringFromCLSID(clsidOld,&buf[6]); + WINE_StringFromCLSID(clsidNew, szClsidNew); + if (RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&hkey)) + { + res = REGDB_E_CLASSNOTREG; + goto done; + } + if (RegCreateKeyA(hkey, "AutoConvertTo", &hkeyConvert)) + { + res = REGDB_E_WRITEREGDB; + goto done; + } + if (RegSetValueExA(hkeyConvert, NULL, 0, + REG_SZ, (LPBYTE)szClsidNew, strlen(szClsidNew)+1)) + { + res = REGDB_E_WRITEREGDB; + goto done; + } + +done: + if (hkeyConvert) RegCloseKey(hkeyConvert); + if (hkey) RegCloseKey(hkey); + + return res; +} + +/*********************************************************************** + * IsEqualGUID [OLE32.76] + * + * Compares two Unique Identifiers. + * + * RETURNS + * TRUE if equal + */ +#undef IsEqualGUID +BOOL WINAPI IsEqualGUID( + REFGUID rguid1, /* [in] unique id 1 */ + REFGUID rguid2 /* [in] unique id 2 */ + ) +{ + return !memcmp(rguid1,rguid2,sizeof(GUID)); +} diff --git a/reactos/lib/ole32/compositemoniker.c b/reactos/lib/ole32/compositemoniker.c new file mode 100644 index 00000000000..337b096c5d3 --- /dev/null +++ b/reactos/lib/ole32/compositemoniker.c @@ -0,0 +1,1702 @@ +/*************************************************************************************** + * CompositeMonikers implementation + * + * Copyright 1999 Noomen Hamza + ***************************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include + + +#define BLOCK_TAB_SIZE 5 /* represent the first size table and it's increment block size */ + +/* CompositeMoniker data structure */ +typedef struct CompositeMonikerImpl{ + + ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/ + + /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether + * two monikers are equal. That's whay IROTData interface is implemented by monikers. + */ + ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/ + + ULONG ref; /* reference counter for this object */ + + IMoniker** tabMoniker; /* dynamaic table containing all components (monikers) of this composite moniker */ + + ULONG tabSize; /* size of tabMoniker */ + + ULONG tabLastIndex; /* first free index in tabMoniker */ + +} CompositeMonikerImpl; + + +/* EnumMoniker data structure */ +typedef struct EnumMonikerImpl{ + + ICOM_VFIELD(IEnumMoniker); /* VTable relative to the IEnumMoniker interface.*/ + + ULONG ref; /* reference counter for this object */ + + IMoniker** tabMoniker; /* dynamic table containing the enumerated monikers */ + + ULONG tabSize; /* size of tabMoniker */ + + ULONG currentPos; /* index pointer on the current moniker */ + +} EnumMonikerImpl; + + +/********************************************************************************/ +/* CompositeMoniker prototype functions : */ + +/* IUnknown prototype functions */ +static HRESULT WINAPI CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject); +static ULONG WINAPI CompositeMonikerImpl_AddRef(IMoniker* iface); +static ULONG WINAPI CompositeMonikerImpl_Release(IMoniker* iface); + +/* IPersist prototype functions */ +static HRESULT WINAPI CompositeMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID); + +/* IPersistStream prototype functions */ +static HRESULT WINAPI CompositeMonikerImpl_IsDirty(IMoniker* iface); +static HRESULT WINAPI CompositeMonikerImpl_Load(IMoniker* iface, IStream* pStm); +static HRESULT WINAPI CompositeMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty); +static HRESULT WINAPI CompositeMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize); + +/* IMoniker prototype functions */ +static HRESULT WINAPI CompositeMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); +static HRESULT WINAPI CompositeMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); +static HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced); +static HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite); +static HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker); +static HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker); +static HRESULT WINAPI CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash); +static HRESULT WINAPI CompositeMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning); +static HRESULT WINAPI CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pCompositeTime); +static HRESULT WINAPI CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk); +static HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix); +static HRESULT WINAPI CompositeMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath); +static HRESULT WINAPI CompositeMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName); +static HRESULT WINAPI CompositeMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut); +static HRESULT WINAPI CompositeMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys); + +/********************************************************************************/ +/* IROTData prototype functions */ + +/* IUnknown prototype functions */ +static HRESULT WINAPI CompositeMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject); +static ULONG WINAPI CompositeMonikerROTDataImpl_AddRef(IROTData* iface); +static ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface); + +/* IROTData prototype function */ +static HRESULT WINAPI CompositeMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData); + +/* Local function used by CompositeMoniker implementation */ +HRESULT WINAPI CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,LPMONIKER pmkFirst, LPMONIKER pmkRest); +HRESULT WINAPI CompositeMonikerImpl_Destroy(CompositeMonikerImpl* iface); + +/********************************************************************************/ +/* IEnumMoniker prototype functions */ + +/* IUnknown prototype functions */ +static HRESULT WINAPI EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject); +static ULONG WINAPI EnumMonikerImpl_AddRef(IEnumMoniker* iface); +static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface); + +/* IEnumMoniker prototype functions */ +static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt,IMoniker** rgelt,ULONG* pceltFetched); +static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt); +static HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface); +static HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum); + +HRESULT WINAPI EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRigth,IEnumMoniker ** ppmk); + +/********************************************************************************/ +/* Virtual function table for the CompositeMonikerImpl class which includes */ +/* IPersist, IPersistStream and IMoniker functions. */ + +static ICOM_VTABLE(IMoniker) VT_CompositeMonikerImpl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + CompositeMonikerImpl_QueryInterface, + CompositeMonikerImpl_AddRef, + CompositeMonikerImpl_Release, + CompositeMonikerImpl_GetClassID, + CompositeMonikerImpl_IsDirty, + CompositeMonikerImpl_Load, + CompositeMonikerImpl_Save, + CompositeMonikerImpl_GetSizeMax, + CompositeMonikerImpl_BindToObject, + CompositeMonikerImpl_BindToStorage, + CompositeMonikerImpl_Reduce, + CompositeMonikerImpl_ComposeWith, + CompositeMonikerImpl_Enum, + CompositeMonikerImpl_IsEqual, + CompositeMonikerImpl_Hash, + CompositeMonikerImpl_IsRunning, + CompositeMonikerImpl_GetTimeOfLastChange, + CompositeMonikerImpl_Inverse, + CompositeMonikerImpl_CommonPrefixWith, + CompositeMonikerImpl_RelativePathTo, + CompositeMonikerImpl_GetDisplayName, + CompositeMonikerImpl_ParseDisplayName, + CompositeMonikerImpl_IsSystemMoniker +}; + +/********************************************************************************/ +/* Virtual function table for the IROTData class. */ +static ICOM_VTABLE(IROTData) VT_ROTDataImpl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + CompositeMonikerROTDataImpl_QueryInterface, + CompositeMonikerROTDataImpl_AddRef, + CompositeMonikerROTDataImpl_Release, + CompositeMonikerROTDataImpl_GetComparaisonData +}; + +/********************************************************************************/ +/* Virtual function table for the IROTData class */ +static ICOM_VTABLE(IEnumMoniker) VT_EnumMonikerImpl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + EnumMonikerImpl_QueryInterface, + EnumMonikerImpl_AddRef, + EnumMonikerImpl_Release, + EnumMonikerImpl_Next, + EnumMonikerImpl_Skip, + EnumMonikerImpl_Reset, + EnumMonikerImpl_Clone +}; + +/******************************************************************************* + * CompositeMoniker_QueryInterface + *******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject) +{ + ICOM_THIS(CompositeMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,riid,ppvObject)); + + /* Perform a sanity check on the parameters.*/ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* Initialize the return parameter */ + *ppvObject = 0; + + /* Compare the riid with the interface IDs implemented by this object.*/ + if (IsEqualIID(&IID_IUnknown, riid) || + IsEqualIID(&IID_IPersist, riid) || + IsEqualIID(&IID_IPersistStream, riid) || + IsEqualIID(&IID_IMoniker, riid) + ) + *ppvObject = iface; + else if (IsEqualIID(&IID_IROTData, riid)) + *ppvObject = (IROTData*)&(This->lpvtbl2); + + /* Check that we obtained an interface.*/ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* Query Interface always increases the reference count by one when it is successful */ + CompositeMonikerImpl_AddRef(iface); + + return S_OK; +} + +/****************************************************************************** + * CompositeMoniker_AddRef + ******************************************************************************/ +ULONG WINAPI CompositeMonikerImpl_AddRef(IMoniker* iface) +{ + ICOM_THIS(CompositeMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + return ++(This->ref); +} + +/****************************************************************************** + * CompositeMoniker_Release + ******************************************************************************/ +ULONG WINAPI CompositeMonikerImpl_Release(IMoniker* iface) +{ + ICOM_THIS(CompositeMonikerImpl,iface); + ULONG i; + + Print(MAX_TRACE, ("(%p)\n",This)); + + This->ref--; + + /* destroy the object if there's no more reference on it */ + if (This->ref==0){ + + /* release all the components before destroying this object */ + for (i=0;itabLastIndex;i++) + IMoniker_Release(This->tabMoniker[i]); + + CompositeMonikerImpl_Destroy(This); + + return 0; + } + return This->ref;; +} + +/****************************************************************************** + * CompositeMoniker_GetClassID + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID) +{ + Print(MAX_TRACE, ("(%p,%p),stub!\n",iface,pClassID)); + + if (pClassID==NULL) + return E_POINTER; + + *pClassID = CLSID_CompositeMoniker; + + return S_OK; +} + +/****************************************************************************** + * CompositeMoniker_IsDirty + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_IsDirty(IMoniker* iface) +{ + /* Note that the OLE-provided implementations of the IPersistStream::IsDirty + method in the OLE-provided moniker interfaces always return S_FALSE because + their internal state never changes. */ + + Print(MAX_TRACE, ("(%p)\n",iface)); + + return S_FALSE; +} + +/****************************************************************************** + * CompositeMoniker_Load + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm) +{ + HRESULT res; + DWORD constant; + CLSID clsid; + WCHAR string[1]={0}; + + ICOM_THIS(CompositeMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p,%p)\n",iface,pStm)); + + /* this function call OleLoadFromStream function for each moniker within this object */ + + /* read the a constant writen by CompositeMonikerImpl_Save (see CompositeMonikerImpl_Save for more details)*/ + res=IStream_Read(pStm,&constant,sizeof(DWORD),NULL); + + if (SUCCEEDED(res)&& constant!=3) + return E_FAIL; + + while(1){ +#if 0 + res=OleLoadFromStream(pStm,&IID_IMoniker,(void**)&This->tabMoniker[This->tabLastIndex]); +#endif + res=ReadClassStm(pStm,&clsid); + Print(MAX_TRACE, ("res=%ld",res)); + if (FAILED(res)) + break; + + if (IsEqualIID(&clsid,&CLSID_FileMoniker)){ + res=CreateFileMoniker(string,&This->tabMoniker[This->tabLastIndex]); + if (FAILED(res)) + break; + res=IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm); + if (FAILED(res)) + break; + } + else if (IsEqualIID(&clsid,&CLSID_ItemMoniker)){ + CreateItemMoniker(string,string,&This->tabMoniker[This->tabLastIndex]); + if (res!=S_OK) + break; + IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm); + if (FAILED(res)) + break; + } + else if (IsEqualIID(&clsid,&CLSID_AntiMoniker)){ + CreateAntiMoniker(&This->tabMoniker[This->tabLastIndex]); + if (FAILED(res)) + break; + IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm); + if (FAILED(res)) + break; + } + else if (IsEqualIID(&clsid,&CLSID_CompositeMoniker)) + return E_FAIL; + + else + { + Print(MIN_TRACE, ("()\n")); + /* FIXME: To whoever wrote this code: It's either return or break. it cannot be both! */ + break; + return E_NOTIMPL; + } + + /* resize the table if needed */ + if (++This->tabLastIndex==This->tabSize){ + + This->tabSize+=BLOCK_TAB_SIZE; + This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); + + if (This->tabMoniker==NULL) + return E_OUTOFMEMORY; + } + } + + return res; +} + +/****************************************************************************** + * CompositeMoniker_Save + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty) +{ + HRESULT res; + IEnumMoniker *enumMk; + IMoniker *pmk; + DWORD constant=3; + + Print(MAX_TRACE, ("(%p,%p,%d)\n",iface,pStm,fClearDirty)); + + /* this function call OleSaveToStream function for each moniker within this object */ + + /* when I tested this function in windows system ! I usually found this constant in the begining of */ + /* the stream I dont known why (there's no indication in specification) ! */ + res=IStream_Write(pStm,&constant,sizeof(constant),NULL); + + IMoniker_Enum(iface,TRUE,&enumMk); + + while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){ + + res=OleSaveToStream((IPersistStream*)pmk,pStm); + + IMoniker_Release(pmk); + + if (FAILED(res)){ + + IEnumMoniker_Release(pmk); + return res; + } + } + + IEnumMoniker_Release(enumMk); + + return S_OK; +} + +/****************************************************************************** + * CompositeMoniker_GetSizeMax + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_GetSizeMax(IMoniker* iface,ULARGE_INTEGER* pcbSize) +{ + IEnumMoniker *enumMk; + IMoniker *pmk; + ULARGE_INTEGER ptmpSize; + + /* the sizeMax of this object is calculated by calling GetSizeMax on each moniker within this object then */ + /* suming all returned sizemax */ + + Print(MAX_TRACE, ("(%p,%p)\n",iface,pcbSize)); + + if (pcbSize!=NULL) + return E_POINTER; + + pcbSize->u.LowPart =0; + pcbSize->u.HighPart=0; + + IMoniker_Enum(iface,TRUE,&enumMk); + + while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==TRUE){ + + IMoniker_GetSizeMax(pmk,&ptmpSize); + + IMoniker_Release(pmk); + + pcbSize->u.LowPart +=ptmpSize.u.LowPart; + pcbSize->u.HighPart+=ptmpSize.u.HighPart; + } + + IEnumMoniker_Release(enumMk); + + return S_OK; +} + +/****************************************************************************** + * Composite-Moniker_Construct (local function) + *******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,LPMONIKER pmkFirst, LPMONIKER pmkRest) +{ + DWORD mkSys; + IEnumMoniker *enumMoniker; + IMoniker *tempMk; + HRESULT res; + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,pmkFirst,pmkRest)); + + /* Initialize the virtual fgunction table. */ + This->lpvtbl1 = &VT_CompositeMonikerImpl; + This->lpvtbl2 = &VT_ROTDataImpl; + This->ref = 0; + + This->tabSize=BLOCK_TAB_SIZE; + This->tabLastIndex=0; + + This->tabMoniker=HeapAlloc(GetProcessHeap(),0,This->tabSize*sizeof(IMoniker)); + if (This->tabMoniker==NULL) + return E_OUTOFMEMORY; + + IMoniker_IsSystemMoniker(pmkFirst,&mkSys); + + /* put the first moniker contents in the begining of the table */ + if (mkSys!=MKSYS_GENERICCOMPOSITE){ + + This->tabMoniker[(This->tabLastIndex)++]=pmkFirst; + IMoniker_AddRef(pmkFirst); + } + else{ + + IMoniker_Enum(pmkFirst,TRUE,&enumMoniker); + + while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){ + + + if (++This->tabLastIndex==This->tabSize){ + + This->tabSize+=BLOCK_TAB_SIZE; + This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); + + if (This->tabMoniker==NULL) + return E_OUTOFMEMORY; + } + } + + IEnumMoniker_Release(enumMoniker); + } + + /* put the rest moniker contents after the first one and make simplification if needed */ + + IMoniker_IsSystemMoniker(pmkRest,&mkSys); + + if (mkSys!=MKSYS_GENERICCOMPOSITE){ + + /* add a simple moniker to the moniker table */ + + res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],pmkRest,TRUE,&tempMk); + + if (res==MK_E_NEEDGENERIC){ + + /* there's no simplification in this case */ + This->tabMoniker[This->tabLastIndex]=pmkRest; + + This->tabLastIndex++; + + IMoniker_AddRef(pmkRest); + } + else if (tempMk==NULL){ + + /* we have an antimoniker after a simple moniker so we can make a simplification in this case */ + IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]); + + This->tabLastIndex--; + } + else if (SUCCEEDED(res)){ + + /* the non-generic composition was successful so we can make a simplification in this case */ + IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]); + + This->tabMoniker[This->tabLastIndex-1]=tempMk; + } else + return res; + + /* resize tabMoniker if needed */ + if (This->tabLastIndex==This->tabSize){ + + This->tabSize+=BLOCK_TAB_SIZE; + + This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); + + if (This->tabMoniker==NULL) + return E_OUTOFMEMORY; + } + } + else{ + + /* add a composite moniker to the moniker table (do the same thing for each moniker within the */ + /* composite moniker as a simple moniker (see above how to add a simple moniker case) ) */ + IMoniker_Enum(pmkRest,TRUE,&enumMoniker); + + while(IEnumMoniker_Next(enumMoniker,1,&This->tabMoniker[This->tabLastIndex],NULL)==S_OK){ + + res=IMoniker_ComposeWith(This->tabMoniker[This->tabLastIndex-1],This->tabMoniker[This->tabLastIndex],TRUE,&tempMk); + + if (res==MK_E_NEEDGENERIC){ + + This->tabLastIndex++; + } + else if (tempMk==NULL){ + + IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]); + IMoniker_Release(This->tabMoniker[This->tabLastIndex]); + This->tabLastIndex--; + } + else{ + + IMoniker_Release(This->tabMoniker[This->tabLastIndex-1]); + + This->tabMoniker[This->tabLastIndex-1]=tempMk; + } + + if (This->tabLastIndex==This->tabSize){ + + This->tabSize+=BLOCK_TAB_SIZE; + + This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); + + if (This->tabMoniker==NULL) + return E_OUTOFMEMORY; + } + } + + IEnumMoniker_Release(enumMoniker); + } + + return S_OK; +} + +/****************************************************************************** + * CompositeMoniker_Destroy (local function) + *******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_Destroy(CompositeMonikerImpl* This) +{ + Print(MAX_TRACE, ("(%p)\n",This)); + + HeapFree(GetProcessHeap(),0,This->tabMoniker); + + HeapFree(GetProcessHeap(),0,This); + + return S_OK; +} + +/****************************************************************************** + * CompositeMoniker_BindToObject + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_BindToObject(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvResult) +{ + HRESULT res; + IRunningObjectTable *prot; + IMoniker *tempMk,*antiMk,*mostRigthMk; + IEnumMoniker *enumMoniker; + + Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult)); + + if (ppvResult==NULL) + return E_POINTER; + + *ppvResult=0; + /* If pmkToLeft is NULL, this method looks for the moniker in the ROT, and if found, queries the retrieved */ + /* object for the requested interface pointer. */ + if(pmkToLeft==NULL){ + + res=IBindCtx_GetRunningObjectTable(pbc,&prot); + + if (SUCCEEDED(res)){ + + /* if the requested class was loaded befor ! we dont need to reload it */ + res = IRunningObjectTable_GetObject(prot,iface,(IUnknown**)ppvResult); + + if (res==S_OK) + return res; + } + } + else{ + /* If pmkToLeft is not NULL, the method recursively calls IMoniker::BindToObject on the rightmost */ + /* component of the composite, passing the rest of the composite as the pmkToLeft parameter for that call */ + + IMoniker_Enum(iface,FALSE,&enumMoniker); + IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); + IEnumMoniker_Release(enumMoniker); + + res=CreateAntiMoniker(&antiMk); + res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + IMoniker_Release(antiMk); + + res=CompositeMonikerImpl_BindToObject(mostRigthMk,pbc,tempMk,riid,ppvResult); + + IMoniker_Release(tempMk); + IMoniker_Release(mostRigthMk); + } + + return res; +} + +/****************************************************************************** + * CompositeMoniker_BindToStorage + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_BindToStorage(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvResult) +{ + HRESULT res; + IMoniker *tempMk,*antiMk,*mostRigthMk; + IEnumMoniker *enumMoniker; + + Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult)); + + *ppvResult=0; + + /* This method recursively calls BindToStorage on the rightmost component of the composite, */ + /* passing the rest of the composite as the pmkToLeft parameter for that call. */ + + if (pmkToLeft!=NULL){ + + IMoniker_Enum(iface,FALSE,&enumMoniker); + IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); + IEnumMoniker_Release(enumMoniker); + + res=CreateAntiMoniker(&antiMk); + res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + IMoniker_Release(antiMk); + + res=CompositeMonikerImpl_BindToStorage(mostRigthMk,pbc,tempMk,riid,ppvResult); + + IMoniker_Release(tempMk); + + IMoniker_Release(mostRigthMk); + + return res; + } + else + return IMoniker_BindToStorage(iface,pbc,NULL,riid,ppvResult); +} + +/****************************************************************************** + * CompositeMoniker_Reduce + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker* iface, + IBindCtx* pbc, + DWORD dwReduceHowFar, + IMoniker** ppmkToLeft, + IMoniker** ppmkReduced) +{ + HRESULT res; + IMoniker *tempMk,*antiMk,*mostRigthMk,*leftReducedComposedMk,*mostRigthReducedMk; + IEnumMoniker *enumMoniker; + + Print(MAX_TRACE, ("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced)); + + if (ppmkReduced==NULL) + return E_POINTER; + + /* This method recursively calls Reduce for each of its component monikers. */ + + if (ppmkToLeft==NULL){ + + IMoniker_Enum(iface,FALSE,&enumMoniker); + IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); + IEnumMoniker_Release(enumMoniker); + + res=CreateAntiMoniker(&antiMk); + res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + IMoniker_Release(antiMk); + + return CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced); + } + else if (*ppmkToLeft==NULL) + + return IMoniker_Reduce(iface,pbc,dwReduceHowFar,NULL,ppmkReduced); + + else{ + + /* separate the composite moniker in to left and right moniker */ + IMoniker_Enum(iface,FALSE,&enumMoniker); + IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); + IEnumMoniker_Release(enumMoniker); + + res=CreateAntiMoniker(&antiMk); + res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + IMoniker_Release(antiMk); + + /* If any of the components reduces itself, the method returns S_OK and passes back a composite */ + /* of the reduced components */ + if (IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,NULL,&mostRigthReducedMk) && + CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk) + ) + + return CreateGenericComposite(leftReducedComposedMk,mostRigthReducedMk,ppmkReduced); + + else{ + /* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/ + + IMoniker_AddRef(iface); + + *ppmkReduced=iface; + + return MK_S_REDUCED_TO_SELF; + } + } +} + +/****************************************************************************** + * CompositeMoniker_ComposeWith + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker* iface, + IMoniker* pmkRight, + BOOL fOnlyIfNotGeneric, + IMoniker** ppmkComposite) +{ + Print(MAX_TRACE, ("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite)); + + if ((ppmkComposite==NULL)||(pmkRight==NULL)) + return E_POINTER; + + *ppmkComposite=0; + + /* If fOnlyIfNotGeneric is TRUE, this method sets *pmkComposite to NULL and returns MK_E_NEEDGENERIC; */ + /* otherwise, the method returns the result of combining the two monikers by calling the */ + /* CreateGenericComposite function */ + + if (fOnlyIfNotGeneric) + return MK_E_NEEDGENERIC; + + return CreateGenericComposite(iface,pmkRight,ppmkComposite); +} + +/****************************************************************************** + * CompositeMoniker_Enum + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) +{ + ICOM_THIS(CompositeMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p,%d,%p)\n",iface,fForward,ppenumMoniker)); + + if (ppenumMoniker == NULL) + return E_POINTER; + + return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabLastIndex,0,fForward,ppenumMoniker); +} + +/****************************************************************************** + * CompositeMoniker_IsEqual + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) +{ + IEnumMoniker *enumMoniker1,*enumMoniker2; + IMoniker *tempMk1,*tempMk2; + HRESULT res1,res2,res; + + Print(MAX_TRACE, ("(%p,%p)\n",iface,pmkOtherMoniker)); + + if (pmkOtherMoniker==NULL) + return S_FALSE; + + /* This method returns S_OK if the components of both monikers are equal when compared in the */ + /* left-to-right order.*/ + IMoniker_Enum(pmkOtherMoniker,TRUE,&enumMoniker1); + + if (enumMoniker1==NULL) + return S_FALSE; + + IMoniker_Enum(iface,TRUE,&enumMoniker2); + + while(1){ + + res1=IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL); + res2=IEnumMoniker_Next(enumMoniker2,1,&tempMk2,NULL); + + if((res1==S_OK)&&(res2==S_OK)){ + + if(IMoniker_IsEqual(tempMk1,tempMk2)==S_FALSE){ + res= S_FALSE; + break; + } + else + continue; + } + else if ( (res1==S_FALSE) && (res2==S_FALSE) ){ + res = S_OK; + break; + } + else{ + res = S_FALSE; + break; + } + + if (res1==S_OK) + IMoniker_Release(tempMk1); + + if (res2==S_OK) + IMoniker_Release(tempMk2); + } + + IEnumMoniker_Release(enumMoniker1); + IEnumMoniker_Release(enumMoniker2); + + return res; +} +/****************************************************************************** + * CompositeMoniker_Hash + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) +{ + Print(MIN_TRACE, ("(),stub!\n")); + + return E_NOTIMPL; +} + +/****************************************************************************** + * CompositeMoniker_IsRunning + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_IsRunning(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + IMoniker* pmkNewlyRunning) +{ + IRunningObjectTable* rot; + HRESULT res; + IMoniker *tempMk,*antiMk,*mostRigthMk; + IEnumMoniker *enumMoniker; + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning)); + + /* If pmkToLeft is non-NULL, this method composes pmkToLeft with this moniker and calls IsRunning on the result.*/ + if (pmkToLeft!=NULL){ + + CreateGenericComposite(pmkToLeft,iface,&tempMk); + + res = IMoniker_IsRunning(tempMk,pbc,NULL,pmkNewlyRunning); + + IMoniker_Release(tempMk); + + return res; + } + else + /* If pmkToLeft is NULL, this method returns S_OK if pmkNewlyRunning is non-NULL and is equal */ + /* to this moniker */ + + if (pmkNewlyRunning!=NULL) + + if (IMoniker_IsEqual(iface,pmkNewlyRunning)==S_OK) + return S_OK; + + else + return S_FALSE; + + else{ + + if (pbc==NULL) + return E_POINTER; + + /* If pmkToLeft and pmkNewlyRunning are both NULL, this method checks the ROT to see whether */ + /* the moniker is running. If so, the method returns S_OK; otherwise, it recursively calls */ + /* IMoniker::IsRunning on the rightmost component of the composite, passing the remainder of */ + /* the composite as the pmkToLeft parameter for that call. */ + + res=IBindCtx_GetRunningObjectTable(pbc,&rot); + + if (FAILED(res)) + return res; + + res = IRunningObjectTable_IsRunning(rot,iface); + IRunningObjectTable_Release(rot); + + if(res==S_OK) + return S_OK; + + else{ + + IMoniker_Enum(iface,FALSE,&enumMoniker); + IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); + IEnumMoniker_Release(enumMoniker); + + res=CreateAntiMoniker(&antiMk); + res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + IMoniker_Release(antiMk); + + res=IMoniker_IsRunning(mostRigthMk,pbc,tempMk,pmkNewlyRunning); + + IMoniker_Release(tempMk); + IMoniker_Release(mostRigthMk); + + return res; + } + } +} + +/****************************************************************************** + * CompositeMoniker_GetTimeOfLastChange + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + FILETIME* pCompositeTime) +{ + IRunningObjectTable* rot; + HRESULT res; + IMoniker *tempMk,*antiMk,*mostRigthMk; + IEnumMoniker *enumMoniker; + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pCompositeTime)); + + if (pCompositeTime==NULL) + return E_INVALIDARG; + + /* This method creates a composite of pmkToLeft (if non-NULL) and this moniker and uses the ROT to */ + /* retrieve the time of last change. If the object is not in the ROT, the method recursively calls */ + /* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */ + /* of the composite as the pmkToLeft parameter for that call. */ + if (pmkToLeft!=NULL){ + + res=CreateGenericComposite(pmkToLeft,iface,&tempMk); + + res=IBindCtx_GetRunningObjectTable(pbc,&rot); + + if (FAILED(res)) + return res; + + if (IRunningObjectTable_GetTimeOfLastChange(rot,tempMk,pCompositeTime)==S_OK) + return res; + else + + IMoniker_Enum(iface,FALSE,&enumMoniker); + IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); + IEnumMoniker_Release(enumMoniker); + + res=CreateAntiMoniker(&antiMk); + res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + IMoniker_Release(antiMk); + + res=CompositeMonikerImpl_GetTimeOfLastChange(mostRigthMk,pbc,tempMk,pCompositeTime); + + IMoniker_Release(tempMk); + IMoniker_Release(mostRigthMk); + + return res; + } + else + return IMoniker_GetTimeOfLastChange(iface,pbc,NULL,pCompositeTime); +} + +/****************************************************************************** + * CompositeMoniker_Inverse + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) +{ + HRESULT res; + IMoniker *tempMk,*antiMk,*mostRigthMk,*tempInvMk,*mostRigthInvMk; + IEnumMoniker *enumMoniker; + + Print(MAX_TRACE, ("(%p,%p)\n",iface,ppmk)); + + if (ppmk==NULL) + return E_POINTER; + + /* This method returns a composite moniker that consists of the inverses of each of the components */ + /* of the original composite, stored in reverse order */ + + res=CreateAntiMoniker(&antiMk); + res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk); + IMoniker_Release(antiMk); + + if (tempMk==NULL) + + return IMoniker_Inverse(iface,ppmk); + + else{ + + IMoniker_Enum(iface,FALSE,&enumMoniker); + IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL); + IEnumMoniker_Release(enumMoniker); + + IMoniker_Inverse(mostRigthMk,&mostRigthInvMk); + CompositeMonikerImpl_Inverse(tempMk,&tempInvMk); + + res=CreateGenericComposite(mostRigthInvMk,tempInvMk,ppmk); + + IMoniker_Release(tempMk); + IMoniker_Release(mostRigthMk); + IMoniker_Release(tempInvMk); + IMoniker_Release(mostRigthInvMk); + + return res; + } +} + +/****************************************************************************** + * CompositeMoniker_CommonPrefixWith + ******************************************************************************/ +HRESULT WINAPI CompositeMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) +{ + DWORD mkSys; + HRESULT res1,res2; + IMoniker *tempMk1,*tempMk2,*mostLeftMk1,*mostLeftMk2; + IEnumMoniker *enumMoniker1,*enumMoniker2; + ULONG i,nbCommonMk=0; + + /* If the other moniker is a composite, this method compares the components of each composite from left */ + /* to right. The returned common prefix moniker might also be a composite moniker, depending on how many */ + /* of the leftmost components were common to both monikers. */ + + if (ppmkPrefix==NULL) + return E_POINTER; + + *ppmkPrefix=0; + + if (pmkOther==NULL) + return MK_E_NOPREFIX; + + IMoniker_IsSystemMoniker(pmkOther,&mkSys); + + if((mkSys==MKSYS_GENERICCOMPOSITE)){ + + IMoniker_Enum(iface,TRUE,&enumMoniker1); + IMoniker_Enum(pmkOther,TRUE,&enumMoniker2); + + while(1){ + + res1=IEnumMoniker_Next(enumMoniker1,1,&mostLeftMk1,NULL); + res2=IEnumMoniker_Next(enumMoniker2,1,&mostLeftMk2,NULL); + + if ((res1==S_FALSE) && (res2==S_FALSE)){ + + /* If the monikers are equal, the method returns MK_S_US and sets ppmkPrefix to this moniker.*/ + *ppmkPrefix=iface; + IMoniker_AddRef(iface); + return MK_S_US; + } + else if ((res1==S_OK) && (res2==S_OK)){ + + if (IMoniker_IsEqual(mostLeftMk1,mostLeftMk2)==S_OK) + + nbCommonMk++; + + else + break; + + } + else if (res1==S_OK){ + + /* If the other moniker is a prefix of this moniker, the method returns MK_S_HIM and sets */ + /* ppmkPrefix to the other moniker. */ + *ppmkPrefix=pmkOther; + return MK_S_HIM; + } + else{ + /* If this moniker is a prefix of the other, this method returns MK_S_ME and sets ppmkPrefix */ + /* to this moniker. */ + *ppmkPrefix=iface; + return MK_S_ME; + } + } + + IEnumMoniker_Release(enumMoniker1); + IEnumMoniker_Release(enumMoniker2); + + /* If there is no common prefix, this method returns MK_E_NOPREFIX and sets ppmkPrefix to NULL. */ + if (nbCommonMk==0) + return MK_E_NOPREFIX; + + IEnumMoniker_Reset(enumMoniker1); + + IEnumMoniker_Next(enumMoniker1,1,&tempMk1,NULL); + + /* if we have more than one commun moniker the result will be a composite moniker */ + if (nbCommonMk>1){ + + /* initialize the common prefix moniker with the composite of two first moniker (from the left)*/ + IEnumMoniker_Next(enumMoniker1,1,&tempMk2,NULL); + CreateGenericComposite(tempMk1,tempMk2,ppmkPrefix); + IMoniker_Release(tempMk1); + IMoniker_Release(tempMk2); + + /* compose all common monikers in a composite moniker */ + for(i=0;iref); + +} + +/****************************************************************************** + * EnumMonikerImpl_Release + ******************************************************************************/ +ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface) +{ + ICOM_THIS(EnumMonikerImpl,iface); + ULONG i + ; + Print(MAX_TRACE, ("(%p)\n",This)); + + This->ref--; + + /* destroy the object if there's no more reference on it */ + if (This->ref==0){ + + for(i=0;itabSize;i++) + IMoniker_Release(This->tabMoniker[i]); + + HeapFree(GetProcessHeap(),0,This->tabMoniker); + HeapFree(GetProcessHeap(),0,This); + + return 0; + } + return This->ref;; +} + +/****************************************************************************** + * EnumMonikerImpl_Next + ******************************************************************************/ +HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt, ULONG* pceltFethed){ + + ICOM_THIS(EnumMonikerImpl,iface); + ULONG i; + + /* retrieve the requested number of moniker from the current position */ + for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++) + + rgelt[i]=This->tabMoniker[This->currentPos++]; + + if (pceltFethed!=NULL) + *pceltFethed= i; + + if (i==celt) + return S_OK; + else + return S_FALSE; +} + +/****************************************************************************** + * EnumMonikerImpl_Skip + ******************************************************************************/ +HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker* iface,ULONG celt){ + + ICOM_THIS(EnumMonikerImpl,iface); + + if ((This->currentPos+celt) >= This->tabSize) + return S_FALSE; + + This->currentPos+=celt; + + return S_OK; +} + +/****************************************************************************** + * EnumMonikerImpl_Reset + ******************************************************************************/ +HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface){ + + ICOM_THIS(EnumMonikerImpl,iface); + + This->currentPos=0; + + return S_OK; +} + +/****************************************************************************** + * EnumMonikerImpl_Clone + ******************************************************************************/ +HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker* iface,IEnumMoniker** ppenum){ + + ICOM_THIS(EnumMonikerImpl,iface); + + return EnumMonikerImpl_CreateEnumMoniker(This->tabMoniker,This->tabSize,This->currentPos,TRUE,ppenum); +} + +/****************************************************************************** + * EnumMonikerImpl_CreateEnumMoniker + ******************************************************************************/ +HRESULT WINAPI EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker, + ULONG tabSize, + ULONG currentPos, + BOOL leftToRigth, + IEnumMoniker ** ppmk) +{ + EnumMonikerImpl* newEnumMoniker; + int i; + + + newEnumMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl)); + + if (newEnumMoniker == 0) + return STG_E_INSUFFICIENTMEMORY; + + if (currentPos > tabSize) + return E_INVALIDARG; + + /* Initialize the virtual function table. */ + ICOM_VTBL(newEnumMoniker) = &VT_EnumMonikerImpl; + newEnumMoniker->ref = 0; + + newEnumMoniker->tabSize=tabSize; + newEnumMoniker->currentPos=currentPos; + + newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(IMoniker)); + + if (newEnumMoniker->tabMoniker==NULL) + return E_OUTOFMEMORY; + + if (leftToRigth) + for (i=0;itabMoniker[i]=tabMoniker[i]; + IMoniker_AddRef(tabMoniker[i]); + } + else + for (i=tabSize-1;i>=0;i--){ + + newEnumMoniker->tabMoniker[tabSize-i-1]=tabMoniker[i]; + IMoniker_AddRef(tabMoniker[i]); + } + + *ppmk=(IEnumMoniker*)newEnumMoniker; + + return S_OK; +} + +/****************************************************************************** + * CreateGenericComposite [OLE.55] + ******************************************************************************/ +HRESULT WINAPI CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest, LPMONIKER* ppmkComposite) +{ + CompositeMonikerImpl* newCompositeMoniker = 0; + HRESULT hr = S_OK; + + Print(MAX_TRACE, ("(%p,%p,%p)\n",pmkFirst,pmkRest,ppmkComposite)); + + if (ppmkComposite==NULL) + return E_POINTER; + + *ppmkComposite=0; + + if (pmkFirst==NULL && pmkRest!=NULL){ + + *ppmkComposite=pmkRest; + return S_OK; + } + else if (pmkFirst!=NULL && pmkRest==NULL){ + *ppmkComposite=pmkFirst; + return S_OK; + } + else if (pmkFirst==NULL && pmkRest==NULL) + return S_OK; + + newCompositeMoniker = HeapAlloc(GetProcessHeap(), 0,sizeof(CompositeMonikerImpl)); + + if (newCompositeMoniker == 0) + return STG_E_INSUFFICIENTMEMORY; + + hr = CompositeMonikerImpl_Construct(newCompositeMoniker,pmkFirst,pmkRest); + + if (FAILED(hr)){ + + HeapFree(GetProcessHeap(),0,newCompositeMoniker); + return hr; + } + if (newCompositeMoniker->tabLastIndex==1) + + hr = IMoniker_QueryInterface(newCompositeMoniker->tabMoniker[0],&IID_IMoniker,(void**)ppmkComposite); + else + + hr = CompositeMonikerImpl_QueryInterface((IMoniker*)newCompositeMoniker,&IID_IMoniker,(void**)ppmkComposite); + + return hr; +} + +/****************************************************************************** + * MonikerCommonPrefixWith [OLE.55] + ******************************************************************************/ +HRESULT WINAPI MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkCommon) +{ + Print(MIN_TRACE, ("(),stub!\n")); + return E_NOTIMPL; +} + + diff --git a/reactos/lib/ole32/datacache.c b/reactos/lib/ole32/datacache.c new file mode 100644 index 00000000000..e5c1ae1f057 --- /dev/null +++ b/reactos/lib/ole32/datacache.c @@ -0,0 +1,2030 @@ +/* + * OLE 2 Data cache + * + * Copyright 1999 Francis Beaudet + * Copyright 2000 Abey George + * + * NOTES: + * The OLE2 data cache supports a whole whack of + * interfaces including: + * IDataObject, IPersistStorage, IViewObject2, + * IOleCache2 and IOleCacheControl. + * + * Most of the implementation details are taken from: Inside OLE + * second edition by Kraig Brockschmidt, + * + * NOTES + * - This implementation of the datacache will let your application + * load documents that have embedded OLE objects in them and it will + * also retrieve the metafile representation of those objects. + * - This implementation of the datacache will also allow your + * application to save new documents with OLE objects in them. + * - The main thing that it doesn't do is allow you to activate + * or modify the OLE objects in any way. + * - I haven't found any good documentation on the real usage of + * the streams created by the data cache. In particular, How to + * determine what the XXX stands for in the stream name + * "\002OlePresXXX". It appears to just be a counter. + * - Also, I don't know the real content of the presentation stream + * header. I was able to figure-out where the extent of the object + * was stored and the aspect, but that's about it. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include + + +/**************************************************************************** + * PresentationDataHeader + * + * This structure represents the header of the \002OlePresXXX stream in + * the OLE object strorage. + * + * Most fields are still unknown. + */ +typedef struct PresentationDataHeader +{ + DWORD unknown1; /* -1 */ + DWORD unknown2; /* 3, possibly CF_METAFILEPICT */ + DWORD unknown3; /* 4, possibly TYMED_ISTREAM */ + DVASPECT dvAspect; + DWORD unknown5; /* -1 */ + + DWORD unknown6; + DWORD unknown7; /* 0 */ + DWORD dwObjectExtentX; + DWORD dwObjectExtentY; + DWORD dwSize; +} PresentationDataHeader; + +/**************************************************************************** + * DataCache + */ +struct DataCache +{ + /* + * List all interface VTables here + */ + ICOM_VTABLE(IDataObject)* lpvtbl1; + ICOM_VTABLE(IUnknown)* lpvtbl2; + ICOM_VTABLE(IPersistStorage)* lpvtbl3; + ICOM_VTABLE(IViewObject2)* lpvtbl4; + ICOM_VTABLE(IOleCache2)* lpvtbl5; + ICOM_VTABLE(IOleCacheControl)* lpvtbl6; + + /* + * Reference count of this object + */ + ULONG ref; + + /* + * IUnknown implementation of the outer object. + */ + IUnknown* outerUnknown; + + /* + * This storage pointer is set through a call to + * IPersistStorage_Load. This is where the visual + * representation of the object is stored. + */ + IStorage* presentationStorage; + + /* + * The user of this object can setup ONE advise sink + * connection with the object. These parameters describe + * that connection. + */ + DWORD sinkAspects; + DWORD sinkAdviseFlag; + IAdviseSink* sinkInterface; + +}; + +typedef struct DataCache DataCache; + +/* + * Here, I define utility macros to help with the casting of the + * "this" parameter. + * There is a version to accomodate all of the VTables implemented + * by this object. + */ +#define _ICOM_THIS_From_IDataObject(class,name) class* this = (class*)name; +#define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((char*)name)-sizeof(void*)); +#define _ICOM_THIS_From_IPersistStorage(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*)); +#define _ICOM_THIS_From_IViewObject2(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*)); +#define _ICOM_THIS_From_IOleCache2(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*)); +#define _ICOM_THIS_From_IOleCacheControl(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*)); + +/* + * Prototypes for the methods of the DataCache class. + */ +static DataCache* DataCache_Construct(REFCLSID clsid, + LPUNKNOWN pUnkOuter); +static void DataCache_Destroy(DataCache* ptrToDestroy); +static HRESULT DataCache_ReadPresentationData(DataCache* this, + DWORD drawAspect, + PresentationDataHeader* header); +static HRESULT DataCache_OpenPresStream(DataCache *this, + DWORD drawAspect, + IStream **pStm); +static HMETAFILE DataCache_ReadPresMetafile(DataCache* this, + DWORD drawAspect); +static void DataCache_FireOnViewChange(DataCache* this, + DWORD aspect, + LONG lindex); + +/* + * Prototypes for the methods of the DataCache class + * that implement non delegating IUnknown methods. + */ +static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface( + IUnknown* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_NDIUnknown_AddRef( + IUnknown* iface); +static ULONG WINAPI DataCache_NDIUnknown_Release( + IUnknown* iface); + +/* + * Prototypes for the methods of the DataCache class + * that implement IDataObject methods. + */ +static HRESULT WINAPI DataCache_IDataObject_QueryInterface( + IDataObject* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IDataObject_AddRef( + IDataObject* iface); +static ULONG WINAPI DataCache_IDataObject_Release( + IDataObject* iface); +static HRESULT WINAPI DataCache_GetData( + IDataObject* iface, + LPFORMATETC pformatetcIn, + STGMEDIUM* pmedium); +static HRESULT WINAPI DataCache_GetDataHere( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium); +static HRESULT WINAPI DataCache_QueryGetData( + IDataObject* iface, + LPFORMATETC pformatetc); +static HRESULT WINAPI DataCache_GetCanonicalFormatEtc( + IDataObject* iface, + LPFORMATETC pformatectIn, + LPFORMATETC pformatetcOut); +static HRESULT WINAPI DataCache_IDataObject_SetData( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease); +static HRESULT WINAPI DataCache_EnumFormatEtc( + IDataObject* iface, + DWORD dwDirection, + IEnumFORMATETC** ppenumFormatEtc); +static HRESULT WINAPI DataCache_DAdvise( + IDataObject* iface, + FORMATETC* pformatetc, + DWORD advf, + IAdviseSink* pAdvSink, + DWORD* pdwConnection); +static HRESULT WINAPI DataCache_DUnadvise( + IDataObject* iface, + DWORD dwConnection); +static HRESULT WINAPI DataCache_EnumDAdvise( + IDataObject* iface, + IEnumSTATDATA** ppenumAdvise); + +/* + * Prototypes for the methods of the DataCache class + * that implement IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface( + IPersistStorage* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IPersistStorage_AddRef( + IPersistStorage* iface); +static ULONG WINAPI DataCache_IPersistStorage_Release( + IPersistStorage* iface); +static HRESULT WINAPI DataCache_GetClassID( + IPersistStorage* iface, + CLSID* pClassID); +static HRESULT WINAPI DataCache_IsDirty( + IPersistStorage* iface); +static HRESULT WINAPI DataCache_InitNew( + IPersistStorage* iface, + IStorage* pStg); +static HRESULT WINAPI DataCache_Load( + IPersistStorage* iface, + IStorage* pStg); +static HRESULT WINAPI DataCache_Save( + IPersistStorage* iface, + IStorage* pStg, + BOOL fSameAsLoad); +static HRESULT WINAPI DataCache_SaveCompleted( + IPersistStorage* iface, + IStorage* pStgNew); +static HRESULT WINAPI DataCache_HandsOffStorage( + IPersistStorage* iface); + +/* + * Prototypes for the methods of the DataCache class + * that implement IViewObject2 methods. + */ +static HRESULT WINAPI DataCache_IViewObject2_QueryInterface( + IViewObject2* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IViewObject2_AddRef( + IViewObject2* iface); +static ULONG WINAPI DataCache_IViewObject2_Release( + IViewObject2* iface); +static HRESULT WINAPI DataCache_Draw( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hdcTargetDev, + HDC hdcDraw, + LPCRECTL lprcBounds, + LPCRECTL lprcWBounds, + IVO_ContCallback pfnContinue, + DWORD dwContinue); +static HRESULT WINAPI DataCache_GetColorSet( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hicTargetDevice, + LOGPALETTE** ppColorSet); +static HRESULT WINAPI DataCache_Freeze( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DWORD* pdwFreeze); +static HRESULT WINAPI DataCache_Unfreeze( + IViewObject2* iface, + DWORD dwFreeze); +static HRESULT WINAPI DataCache_SetAdvise( + IViewObject2* iface, + DWORD aspects, + DWORD advf, + IAdviseSink* pAdvSink); +static HRESULT WINAPI DataCache_GetAdvise( + IViewObject2* iface, + DWORD* pAspects, + DWORD* pAdvf, + IAdviseSink** ppAdvSink); +static HRESULT WINAPI DataCache_GetExtent( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + DVTARGETDEVICE* ptd, + LPSIZEL lpsizel); + +/* + * Prototypes for the methods of the DataCache class + * that implement IOleCache2 methods. + */ +static HRESULT WINAPI DataCache_IOleCache2_QueryInterface( + IOleCache2* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IOleCache2_AddRef( + IOleCache2* iface); +static ULONG WINAPI DataCache_IOleCache2_Release( + IOleCache2* iface); +static HRESULT WINAPI DataCache_Cache( + IOleCache2* iface, + FORMATETC* pformatetc, + DWORD advf, + DWORD* pdwConnection); +static HRESULT WINAPI DataCache_Uncache( + IOleCache2* iface, + DWORD dwConnection); +static HRESULT WINAPI DataCache_EnumCache( + IOleCache2* iface, + IEnumSTATDATA** ppenumSTATDATA); +static HRESULT WINAPI DataCache_InitCache( + IOleCache2* iface, + IDataObject* pDataObject); +static HRESULT WINAPI DataCache_IOleCache2_SetData( + IOleCache2* iface, + FORMATETC* pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease); +static HRESULT WINAPI DataCache_UpdateCache( + IOleCache2* iface, + LPDATAOBJECT pDataObject, + DWORD grfUpdf, + LPVOID pReserved); +static HRESULT WINAPI DataCache_DiscardCache( + IOleCache2* iface, + DWORD dwDiscardOptions); + +/* + * Prototypes for the methods of the DataCache class + * that implement IOleCacheControl methods. + */ +static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface( + IOleCacheControl* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IOleCacheControl_AddRef( + IOleCacheControl* iface); +static ULONG WINAPI DataCache_IOleCacheControl_Release( + IOleCacheControl* iface); +static HRESULT WINAPI DataCache_OnRun( + IOleCacheControl* iface, + LPDATAOBJECT pDataObject); +static HRESULT WINAPI DataCache_OnStop( + IOleCacheControl* iface); + +/* + * Virtual function tables for the DataCache class. + */ +static ICOM_VTABLE(IUnknown) DataCache_NDIUnknown_VTable = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + DataCache_NDIUnknown_QueryInterface, + DataCache_NDIUnknown_AddRef, + DataCache_NDIUnknown_Release +}; + +static ICOM_VTABLE(IDataObject) DataCache_IDataObject_VTable = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + DataCache_IDataObject_QueryInterface, + DataCache_IDataObject_AddRef, + DataCache_IDataObject_Release, + DataCache_GetData, + DataCache_GetDataHere, + DataCache_QueryGetData, + DataCache_GetCanonicalFormatEtc, + DataCache_IDataObject_SetData, + DataCache_EnumFormatEtc, + DataCache_DAdvise, + DataCache_DUnadvise, + DataCache_EnumDAdvise +}; + +static ICOM_VTABLE(IPersistStorage) DataCache_IPersistStorage_VTable = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + DataCache_IPersistStorage_QueryInterface, + DataCache_IPersistStorage_AddRef, + DataCache_IPersistStorage_Release, + DataCache_GetClassID, + DataCache_IsDirty, + DataCache_InitNew, + DataCache_Load, + DataCache_Save, + DataCache_SaveCompleted, + DataCache_HandsOffStorage +}; + +static ICOM_VTABLE(IViewObject2) DataCache_IViewObject2_VTable = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + DataCache_IViewObject2_QueryInterface, + DataCache_IViewObject2_AddRef, + DataCache_IViewObject2_Release, + DataCache_Draw, + DataCache_GetColorSet, + DataCache_Freeze, + DataCache_Unfreeze, + DataCache_SetAdvise, + DataCache_GetAdvise, + DataCache_GetExtent +}; + +static ICOM_VTABLE(IOleCache2) DataCache_IOleCache2_VTable = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + DataCache_IOleCache2_QueryInterface, + DataCache_IOleCache2_AddRef, + DataCache_IOleCache2_Release, + DataCache_Cache, + DataCache_Uncache, + DataCache_EnumCache, + DataCache_InitCache, + DataCache_IOleCache2_SetData, + DataCache_UpdateCache, + DataCache_DiscardCache +}; + +static ICOM_VTABLE(IOleCacheControl) DataCache_IOleCacheControl_VTable = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + DataCache_IOleCacheControl_QueryInterface, + DataCache_IOleCacheControl_AddRef, + DataCache_IOleCacheControl_Release, + DataCache_OnRun, + DataCache_OnStop +}; + +/****************************************************************************** + * CreateDataCache [OLE32.54] + */ +HRESULT WINAPI CreateDataCache( + LPUNKNOWN pUnkOuter, + REFCLSID rclsid, + REFIID riid, + LPVOID* ppvObj) +{ + DataCache* newCache = NULL; + HRESULT hr = S_OK; + + Print(MAX_TRACE, ("(%s, %p, %s, %p)\n", debugstr_guid(rclsid), pUnkOuter, debugstr_guid(riid), ppvObj)); + + /* + * Sanity check + */ + if (ppvObj==0) + return E_POINTER; + + *ppvObj = 0; + + /* + * If this cache is constructed for aggregation, make sure + * the caller is requesting the IUnknown interface. + * This is necessary because it's the only time the non-delegating + * IUnknown pointer can be returned to the outside. + */ + if ( (pUnkOuter!=NULL) && + (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) ) + return CLASS_E_NOAGGREGATION; + + /* + * Try to construct a new instance of the class. + */ + newCache = DataCache_Construct(rclsid, + pUnkOuter); + + if (newCache == 0) + return E_OUTOFMEMORY; + + /* + * Make sure it supports the interface required by the caller. + */ + hr = IUnknown_QueryInterface((IUnknown*)&(newCache->lpvtbl2), riid, ppvObj); + + /* + * Release the reference obtained in the constructor. If + * the QueryInterface was unsuccessful, it will free the class. + */ + IUnknown_Release((IUnknown*)&(newCache->lpvtbl2)); + + return hr; +} + +/********************************************************* + * Method implementation for DataCache class. + */ +static DataCache* DataCache_Construct( + REFCLSID clsid, + LPUNKNOWN pUnkOuter) +{ + DataCache* newObject = 0; + + /* + * Allocate space for the object. + */ + newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache)); + + if (newObject==0) + return newObject; + + /* + * Initialize the virtual function table. + */ + newObject->lpvtbl1 = &DataCache_IDataObject_VTable; + newObject->lpvtbl2 = &DataCache_NDIUnknown_VTable; + newObject->lpvtbl3 = &DataCache_IPersistStorage_VTable; + newObject->lpvtbl4 = &DataCache_IViewObject2_VTable; + newObject->lpvtbl5 = &DataCache_IOleCache2_VTable; + newObject->lpvtbl6 = &DataCache_IOleCacheControl_VTable; + + /* + * Start with one reference count. The caller of this function + * must release the interface pointer when it is done. + */ + newObject->ref = 1; + + /* + * Initialize the outer unknown + * We don't keep a reference on the outer unknown since, the way + * aggregation works, our lifetime is at least as large as it's + * lifetime. + */ + if (pUnkOuter==NULL) + pUnkOuter = (IUnknown*)&(newObject->lpvtbl2); + + newObject->outerUnknown = pUnkOuter; + + /* + * Initialize the other members of the structure. + */ + newObject->presentationStorage = NULL; + newObject->sinkAspects = 0; + newObject->sinkAdviseFlag = 0; + newObject->sinkInterface = 0; + + return newObject; +} + +static void DataCache_Destroy( + DataCache* ptrToDestroy) +{ + Print(MAX_TRACE, ("()\n")); + + if (ptrToDestroy->sinkInterface != NULL) + { + IAdviseSink_Release(ptrToDestroy->sinkInterface); + ptrToDestroy->sinkInterface = NULL; + } + + if (ptrToDestroy->presentationStorage != NULL) + { + IStorage_Release(ptrToDestroy->presentationStorage); + ptrToDestroy->presentationStorage = NULL; + } + + /* + * Free the datacache pointer. + */ + HeapFree(GetProcessHeap(), 0, ptrToDestroy); +} + +/************************************************************************ + * DataCache_ReadPresentationData + * + * This method will read information for the requested presentation + * into the given structure. + * + * Param: + * this - Pointer to the DataCache object + * drawAspect - The aspect of the object that we wish to draw. + * header - The structure containing information about this + * aspect of the object. + */ +static HRESULT DataCache_ReadPresentationData( + DataCache* this, + DWORD drawAspect, + PresentationDataHeader* header) +{ + IStream* presStream = NULL; + HRESULT hres; + + /* + * Open the presentation stream. + */ + hres = DataCache_OpenPresStream( + this, + drawAspect, + &presStream); + + if (FAILED(hres)) + return hres; + + /* + * Read the header. + */ + + hres = IStream_Read( + presStream, + header, + sizeof(PresentationDataHeader), + NULL); + + /* + * Cleanup. + */ + IStream_Release(presStream); + + /* + * We don't want to propagate any other error + * code than a failure. + */ + if (hres!=S_OK) + hres = E_FAIL; + + return hres; +} + +/************************************************************************ + * DataCache_FireOnViewChange + * + * This method will fire an OnViewChange notification to the advise + * sink registered with the datacache. + * + * See IAdviseSink::OnViewChange for more details. + */ +static void DataCache_FireOnViewChange( + DataCache* this, + DWORD aspect, + LONG lindex) +{ + Print(MAX_TRACE, ("(%p, %lx, %ld)\n", this, aspect, lindex)); + + /* + * The sink supplies a filter when it registers + * we make sure we only send the notifications when that + * filter matches. + */ + if ((this->sinkAspects & aspect) != 0) + { + if (this->sinkInterface != NULL) + { + IAdviseSink_OnViewChange(this->sinkInterface, + aspect, + lindex); + + /* + * Some sinks want to be unregistered automatically when + * the first notification goes out. + */ + if ( (this->sinkAdviseFlag & ADVF_ONLYONCE) != 0) + { + IAdviseSink_Release(this->sinkInterface); + + this->sinkInterface = NULL; + this->sinkAspects = 0; + this->sinkAdviseFlag = 0; + } + } + } +} + +/* Helper for DataCache_OpenPresStream */ +static BOOL DataCache_IsPresentationStream(const STATSTG *elem) +{ +#if 0 + /* The presentation streams have names of the form "\002OlePresXXX", + * where XXX goes from 000 to 999. */ + static const WCHAR OlePres[] = { 2,'O','l','e','P','r','e','s' }; + + LPCWSTR name = elem->pwcsName; + + return (elem->type == STGTY_STREAM) + && (elem->cbSize.u.LowPart >= sizeof(PresentationDataHeader)) + && (lstrlenW(name) == 11) + && (strncmpW(name, OlePres, 8) == 0) + && (name[8] >= '0') && (name[8] <= '9') + && (name[9] >= '0') && (name[9] <= '9') + && (name[10] >= '0') && (name[10] <= '9'); +#else + UNIMPLEMENTED; + return FALSE; +#endif +} + +/************************************************************************ + * DataCache_OpenPresStream + * + * This method will find the stream for the given presentation. It makes + * no attempt at fallback. + * + * Param: + * this - Pointer to the DataCache object + * drawAspect - The aspect of the object that we wish to draw. + * pStm - A returned stream. It points to the beginning of the + * - presentation data, including the header. + * + * Errors: + * S_OK The requested stream has been opened. + * OLE_E_BLANK The requested stream could not be found. + * Quite a few others I'm too lazy to map correctly. + * + * Notes: + * Algorithm: Scan the elements of the presentation storage, looking + * for presentation streams. For each presentation stream, + * load the header and check to see if the aspect maches. + * + * If a fallback is desired, just opening the first presentation stream + * is a possibility. + */ +static HRESULT DataCache_OpenPresStream( + DataCache *this, + DWORD drawAspect, + IStream **ppStm) +{ + STATSTG elem; + IEnumSTATSTG *pEnum; + HRESULT hr; + + if (!ppStm) return E_POINTER; + + hr = IStorage_EnumElements(this->presentationStorage, 0, NULL, 0, &pEnum); + if (FAILED(hr)) return hr; + + while ((hr = IEnumSTATSTG_Next(pEnum, 1, &elem, NULL)) == S_OK) + { + if (DataCache_IsPresentationStream(&elem)) + { + IStream *pStm; + + hr = IStorage_OpenStream(this->presentationStorage, elem.pwcsName, + NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, + &pStm); + if (SUCCEEDED(hr)) + { + PresentationDataHeader header; + ULONG actual_read; + + hr = IStream_Read(pStm, &header, sizeof(header), &actual_read); + + /* can't use SUCCEEDED(hr): S_FALSE counts as an error */ + if (hr == S_OK && actual_read == sizeof(header) + && header.dvAspect == drawAspect) + { + /* Rewind the stream before returning it. */ + LARGE_INTEGER offset; + offset.u.LowPart = 0; + offset.u.HighPart = 0; + IStream_Seek(pStm, offset, STREAM_SEEK_SET, NULL); + + *ppStm = pStm; + + CoTaskMemFree(elem.pwcsName); + IEnumSTATSTG_Release(pEnum); + + return S_OK; + } + + IStream_Release(pStm); + } + } + + CoTaskMemFree(elem.pwcsName); + } + + IEnumSTATSTG_Release(pEnum); + + return (hr == S_FALSE ? OLE_E_BLANK : hr); +} + +/************************************************************************ + * DataCache_ReadPresentationData + * + * This method will read information for the requested presentation + * into the given structure. + * + * Param: + * this - Pointer to the DataCache object + * drawAspect - The aspect of the object that we wish to draw. + * + * Returns: + * This method returns a metafile handle if it is successful. + * it will return 0 if not. + */ +static HMETAFILE DataCache_ReadPresMetafile( + DataCache* this, + DWORD drawAspect) +{ + LARGE_INTEGER offset; + IStream* presStream = NULL; + HRESULT hres; + void* metafileBits; + STATSTG streamInfo; + HMETAFILE newMetafile = 0; + + /* + * Open the presentation stream. + */ + hres = DataCache_OpenPresStream( + this, + drawAspect, + &presStream); + + if (FAILED(hres)) + return newMetafile; + + /* + * Get the size of the stream. + */ + hres = IStream_Stat(presStream, + &streamInfo, + STATFLAG_NONAME); + + /* + * Skip the header + */ + offset.u.HighPart = 0; + offset.u.LowPart = sizeof(PresentationDataHeader); + + hres = IStream_Seek( + presStream, + offset, + STREAM_SEEK_SET, + NULL); + + streamInfo.cbSize.u.LowPart -= offset.u.LowPart; + + /* + * Allocate a buffer for the metafile bits. + */ + metafileBits = HeapAlloc(GetProcessHeap(), + 0, + streamInfo.cbSize.u.LowPart); + + /* + * Read the metafile bits. + */ + hres = IStream_Read( + presStream, + metafileBits, + streamInfo.cbSize.u.LowPart, + NULL); + + /* + * Create a metafile with those bits. + */ + if (SUCCEEDED(hres)) + { + newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.u.LowPart, metafileBits); + } + + /* + * Cleanup. + */ + HeapFree(GetProcessHeap(), 0, metafileBits); + IStream_Release(presStream); + + if (newMetafile==0) + hres = E_FAIL; + + return newMetafile; +} + +/********************************************************* + * Method implementation for the non delegating IUnknown + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_NDIUnknown_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + * + * This version of QueryInterface will not delegate it's implementation + * to the outer unknown. + */ +static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface( + IUnknown* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_NDIUnknown(DataCache, iface); + + /* + * Perform a sanity check on the parameters. + */ + if ( (this==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = iface; + } + else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0) + { + *ppvObject = (IDataObject*)&(this->lpvtbl1); + } + else if ( (memcmp(&IID_IPersistStorage, riid, sizeof(IID_IPersistStorage)) == 0) || + (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0) ) + { + *ppvObject = (IPersistStorage*)&(this->lpvtbl3); + } + else if ( (memcmp(&IID_IViewObject, riid, sizeof(IID_IViewObject)) == 0) || + (memcmp(&IID_IViewObject2, riid, sizeof(IID_IViewObject2)) == 0) ) + { + *ppvObject = (IViewObject2*)&(this->lpvtbl4); + } + else if ( (memcmp(&IID_IOleCache, riid, sizeof(IID_IOleCache)) == 0) || + (memcmp(&IID_IOleCache2, riid, sizeof(IID_IOleCache2)) == 0) ) + { + *ppvObject = (IOleCache2*)&(this->lpvtbl5); + } + else if (memcmp(&IID_IOleCacheControl, riid, sizeof(IID_IOleCacheControl)) == 0) + { + *ppvObject = (IOleCacheControl*)&(this->lpvtbl6); + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + { + Print(MID_TRACE, ( "() : asking for unsupported interface %s\n", PRINT_GUID(riid))); + return E_NOINTERFACE; + } + + /* + * Query Interface always increases the reference count by one when it is + * successful. + */ + IUnknown_AddRef((IUnknown*)*ppvObject); + + return S_OK;; +} + +/************************************************************************ + * DataCache_NDIUnknown_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + * + * This version of QueryInterface will not delegate it's implementation + * to the outer unknown. + */ +static ULONG WINAPI DataCache_NDIUnknown_AddRef( + IUnknown* iface) +{ + _ICOM_THIS_From_NDIUnknown(DataCache, iface); + + this->ref++; + + return this->ref; +} + +/************************************************************************ + * DataCache_NDIUnknown_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + * + * This version of QueryInterface will not delegate it's implementation + * to the outer unknown. + */ +static ULONG WINAPI DataCache_NDIUnknown_Release( + IUnknown* iface) +{ + _ICOM_THIS_From_NDIUnknown(DataCache, iface); + + /* + * Decrease the reference count on this object. + */ + this->ref--; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (this->ref==0) + { + DataCache_Destroy(this); + + return 0; + } + + return this->ref; +} + +/********************************************************* + * Method implementation for the IDataObject + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IDataObject_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IDataObject_QueryInterface( + IDataObject* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IDataObject(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IDataObject_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IDataObject_AddRef( + IDataObject* iface) +{ + _ICOM_THIS_From_IDataObject(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IDataObject_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IDataObject_Release( + IDataObject* iface) +{ + _ICOM_THIS_From_IDataObject(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +/************************************************************************ + * DataCache_GetData + * + * Get Data from a source dataobject using format pformatetcIn->cfFormat + * See Windows documentation for more details on GetData. + * TODO: Currently only CF_METAFILEPICT is implemented + */ +static HRESULT WINAPI DataCache_GetData( + IDataObject* iface, + LPFORMATETC pformatetcIn, + STGMEDIUM* pmedium) +{ + HRESULT hr = 0; + HRESULT hrRet = E_UNEXPECTED; + IPersistStorage *pPersistStorage = 0; + IStorage *pStorage = 0; + IStream *pStream = 0; + OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0}; + HGLOBAL hGlobalMF = 0; + void *mfBits = 0; + PresentationDataHeader pdh; + METAFILEPICT *mfPict; + HMETAFILE hMetaFile = 0; + + if (pformatetcIn->cfFormat == CF_METAFILEPICT) + { + /* Get the Persist Storage */ + + hr = IDataObject_QueryInterface(iface, &IID_IPersistStorage, (void**)&pPersistStorage); + + if (hr != S_OK) + goto cleanup; + + /* Create a doc file to copy the doc to a storage */ + + hr = StgCreateDocfile(NULL, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pStorage); + + if (hr != S_OK) + goto cleanup; + + /* Save it to storage */ +#if 0 + hr = OleSave(pPersistStorage, pStorage, FALSE); +#else + Print(MIN_TRACE, ("OleSave() not found\n")); +#endif + + if (hr != S_OK) + goto cleanup; + + /* Open the Presentation data srteam */ + + hr = IStorage_OpenStream(pStorage, name, 0, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &pStream); + + if (hr != S_OK) + goto cleanup; + + /* Read the presentation header */ + + hr = IStream_Read(pStream, &pdh, sizeof(PresentationDataHeader), NULL); + + if (hr != S_OK) + goto cleanup; + + mfBits = HeapAlloc(GetProcessHeap(), 0, pdh.dwSize); + + /* Read the Metafile bits */ + + hr = IStream_Read(pStream, mfBits, pdh.dwSize, NULL); + + if (hr != S_OK) + goto cleanup; + + /* Create the metafile and place it in the STGMEDIUM structure */ + + hMetaFile = SetMetaFileBitsEx(pdh.dwSize, mfBits); + + hGlobalMF = GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, sizeof(METAFILEPICT)); + mfPict = (METAFILEPICT *)GlobalLock(hGlobalMF); +#if 0 + mfPict->hMF = hMetaFile; +#else + Print(MIN_TRACE, ("Depending on MetaFile implementation\n")); +#endif + + GlobalUnlock(hGlobalMF); + + pmedium->u.hGlobal = hGlobalMF; + pmedium->tymed = TYMED_MFPICT; + hrRet = S_OK; + +cleanup: + + if (mfBits) + HeapFree(GetProcessHeap(), 0, mfBits); + + if (pStream) + IStream_Release(pStream); + + if (pStorage) + IStorage_Release(pStorage); + + if (pPersistStorage) + IPersistStorage_Release(pPersistStorage); + + return hrRet; + } + + /* TODO: Other formats are not implemented */ + + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_GetDataHere( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_QueryGetData( + IDataObject* iface, + LPFORMATETC pformatetc) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_EnumFormatEtc (IDataObject) + * + * The data cache doesn't implement this method. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_GetCanonicalFormatEtc( + IDataObject* iface, + LPFORMATETC pformatectIn, + LPFORMATETC pformatetcOut) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_IDataObject_SetData (IDataObject) + * + * This method is delegated to the IOleCache2 implementation. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_IDataObject_SetData( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease) +{ + IOleCache2* oleCache = NULL; + HRESULT hres; + + Print(MAX_TRACE, ("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease)); + + hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache); + + if (FAILED(hres)) + return E_UNEXPECTED; + + hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease); + + IOleCache2_Release(oleCache); + + return hres;; +} + +/************************************************************************ + * DataCache_EnumFormatEtc (IDataObject) + * + * The data cache doesn't implement this method. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_EnumFormatEtc( + IDataObject* iface, + DWORD dwDirection, + IEnumFORMATETC** ppenumFormatEtc) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_DAdvise (IDataObject) + * + * The data cache doesn't support connections. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_DAdvise( + IDataObject* iface, + FORMATETC* pformatetc, + DWORD advf, + IAdviseSink* pAdvSink, + DWORD* pdwConnection) +{ + UNIMPLEMENTED; + return OLE_E_ADVISENOTSUPPORTED; +} + +/************************************************************************ + * DataCache_DUnadvise (IDataObject) + * + * The data cache doesn't support connections. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_DUnadvise( + IDataObject* iface, + DWORD dwConnection) +{ + UNIMPLEMENTED; + return OLE_E_NOCONNECTION; +} + +/************************************************************************ + * DataCache_EnumDAdvise (IDataObject) + * + * The data cache doesn't support connections. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_EnumDAdvise( + IDataObject* iface, + IEnumSTATDATA** ppenumAdvise) +{ + UNIMPLEMENTED; + return OLE_E_ADVISENOTSUPPORTED; +} + +/********************************************************* + * Method implementation for the IDataObject + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IPersistStorage_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface( + IPersistStorage* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IPersistStorage_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IPersistStorage_AddRef( + IPersistStorage* iface) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IPersistStorage_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IPersistStorage_Release( + IPersistStorage* iface) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +/************************************************************************ + * DataCache_GetClassID (IPersistStorage) + * + * The data cache doesn't implement this method. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_GetClassID( + IPersistStorage* iface, + CLSID* pClassID) +{ + Print(MAX_TRACE, ("(%p, %p)\n", iface, pClassID)); + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_IsDirty (IPersistStorage) + * + * Until we actully connect to a running object and retrieve new + * information to it, we never get dirty. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_IsDirty( + IPersistStorage* iface) +{ + Print(MAX_TRACE, ("(%p)\n", iface)); + + return S_FALSE; +} + +/************************************************************************ + * DataCache_InitNew (IPersistStorage) + * + * The data cache implementation of IPersistStorage_InitNew simply stores + * the storage pointer. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_InitNew( + IPersistStorage* iface, + IStorage* pStg) +{ + Print(MAX_TRACE, ("(%p, %p)\n", iface, pStg)); + + return DataCache_Load(iface, pStg); +} + +/************************************************************************ + * DataCache_Load (IPersistStorage) + * + * The data cache implementation of IPersistStorage_Load doesn't + * actually load anything. Instead, it holds on to the storage pointer + * and it will load the presentation information when the + * IDataObject_GetData or IViewObject2_Draw methods are called. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_Load( + IPersistStorage* iface, + IStorage* pStg) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + Print(MAX_TRACE, ("(%p, %p)\n", iface, pStg)); + + if (this->presentationStorage != NULL) + { + IStorage_Release(this->presentationStorage); + } + + this->presentationStorage = pStg; + + if (this->presentationStorage != NULL) + { + IStorage_AddRef(this->presentationStorage); + } + return S_OK; +} + +/************************************************************************ + * DataCache_Save (IPersistStorage) + * + * Until we actully connect to a running object and retrieve new + * information to it, we never have to save anything. However, it is + * our responsability to copy the information when saving to a new + * storage. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_Save( + IPersistStorage* iface, + IStorage* pStg, + BOOL fSameAsLoad) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + Print(MAX_TRACE, ("(%p, %p, %d)\n", iface, pStg, fSameAsLoad)); + + if ( (!fSameAsLoad) && + (this->presentationStorage!=NULL) ) + { + return IStorage_CopyTo(this->presentationStorage, + 0, + NULL, + NULL, + pStg); + } + + return S_OK; +} + +/************************************************************************ + * DataCache_SaveCompleted (IPersistStorage) + * + * This method is called to tell the cache to release the storage + * pointer it's currentlu holding. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_SaveCompleted( + IPersistStorage* iface, + IStorage* pStgNew) +{ + Print(MAX_TRACE, ("(%p, %p)\n", iface, pStgNew)); + + if (pStgNew) + { + /* + * First, make sure we get our hands off any storage we have. + */ + + DataCache_HandsOffStorage(iface); + + /* + * Then, attach to the new storage. + */ + + DataCache_Load(iface, pStgNew); + } + + return S_OK; +} + +/************************************************************************ + * DataCache_HandsOffStorage (IPersistStorage) + * + * This method is called to tell the cache to release the storage + * pointer it's currentlu holding. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_HandsOffStorage( + IPersistStorage* iface) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + Print(MAX_TRACE, ("(%p)\n", iface)); + + if (this->presentationStorage != NULL) + { + IStorage_Release(this->presentationStorage); + this->presentationStorage = NULL; + } + + return S_OK; +} + +/********************************************************* + * Method implementation for the IViewObject2 + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IViewObject2_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IViewObject2_QueryInterface( + IViewObject2* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IViewObject2_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IViewObject2_AddRef( + IViewObject2* iface) +{ + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IViewObject2_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IViewObject2_Release( + IViewObject2* iface) +{ + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +/************************************************************************ + * DataCache_Draw (IViewObject2) + * + * This method will draw the cached representation of the object + * to the given device context. + * + * See Windows documentation for more details on IViewObject2 methods. + */ +static HRESULT WINAPI DataCache_Draw( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hdcTargetDev, + HDC hdcDraw, + LPCRECTL lprcBounds, + LPCRECTL lprcWBounds, + IVO_ContCallback pfnContinue, + DWORD dwContinue) +{ + PresentationDataHeader presData; + HMETAFILE presMetafile = 0; + HRESULT hres; + + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + Print(MAX_TRACE, ("(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n", + iface, + dwDrawAspect, + lindex, + pvAspect, + hdcTargetDev, + hdcDraw, + lprcBounds, + lprcWBounds, + pfnContinue, + dwContinue)); + + /* + * Sanity check + */ + if (lprcBounds==NULL) + return E_INVALIDARG; + + /* + * First, we need to retrieve the dimensions of the + * image in the metafile. + */ + hres = DataCache_ReadPresentationData(this, + dwDrawAspect, + &presData); + + if (FAILED(hres)) + return hres; + + /* + * Then, we can extract the metafile itself from the cached + * data. + * + * FIXME Unless it isn't a metafile. I think it could be any CF_XXX type, + * particularly CF_DIB. + */ + presMetafile = DataCache_ReadPresMetafile(this, + dwDrawAspect); + + /* + * If we have a metafile, just draw baby... + * We have to be careful not to modify the state of the + * DC. + */ + if (presMetafile!=0) + { + INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC); + SIZE oldWindowExt; + SIZE oldViewportExt; + POINT oldViewportOrg; + + SetWindowExtEx(hdcDraw, + presData.dwObjectExtentX, + presData.dwObjectExtentY, + &oldWindowExt); + + SetViewportExtEx(hdcDraw, + lprcBounds->right - lprcBounds->left, + lprcBounds->bottom - lprcBounds->top, + &oldViewportExt); + + SetViewportOrgEx(hdcDraw, + lprcBounds->left, + lprcBounds->top, + &oldViewportOrg); + + PlayMetaFile(hdcDraw, presMetafile); + + SetWindowExtEx(hdcDraw, + oldWindowExt.cx, + oldWindowExt.cy, + NULL); + + SetViewportExtEx(hdcDraw, + oldViewportExt.cx, + oldViewportExt.cy, + NULL); + + SetViewportOrgEx(hdcDraw, + oldViewportOrg.x, + oldViewportOrg.y, + NULL); + + SetMapMode(hdcDraw, prevMapMode); + + DeleteMetaFile(presMetafile); + } + + return S_OK; +} + +static HRESULT WINAPI DataCache_GetColorSet( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hicTargetDevice, + LOGPALETTE** ppColorSet) +{ +UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_Freeze( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DWORD* pdwFreeze) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_Unfreeze( + IViewObject2* iface, + DWORD dwFreeze) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_SetAdvise (IViewObject2) + * + * This sets-up an advisory sink with the data cache. When the object's + * view changes, this sink is called. + * + * See Windows documentation for more details on IViewObject2 methods. + */ +static HRESULT WINAPI DataCache_SetAdvise( + IViewObject2* iface, + DWORD aspects, + DWORD advf, + IAdviseSink* pAdvSink) +{ + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + Print(MAX_TRACE, ("(%p, %lx, %lx, %p)\n", iface, aspects, advf, pAdvSink)); + + /* + * A call to this function removes the previous sink + */ + if (this->sinkInterface != NULL) + { + IAdviseSink_Release(this->sinkInterface); + this->sinkInterface = NULL; + this->sinkAspects = 0; + this->sinkAdviseFlag = 0; + } + + /* + * Now, setup the new one. + */ + if (pAdvSink!=NULL) + { + this->sinkInterface = pAdvSink; + this->sinkAspects = aspects; + this->sinkAdviseFlag = advf; + + IAdviseSink_AddRef(this->sinkInterface); + } + + /* + * When the ADVF_PRIMEFIRST flag is set, we have to advise the + * sink immediately. + */ + if (advf & ADVF_PRIMEFIRST) + { + DataCache_FireOnViewChange(this, + DVASPECT_CONTENT, + -1); + } + + return S_OK; +} + +/************************************************************************ + * DataCache_GetAdvise (IViewObject2) + * + * This method queries the current state of the advise sink + * installed on the data cache. + * + * See Windows documentation for more details on IViewObject2 methods. + */ +static HRESULT WINAPI DataCache_GetAdvise( + IViewObject2* iface, + DWORD* pAspects, + DWORD* pAdvf, + IAdviseSink** ppAdvSink) +{ + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + Print(MAX_TRACE, ("(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink)); + + /* + * Just copy all the requested values. + */ + if (pAspects!=NULL) + *pAspects = this->sinkAspects; + + if (pAdvf!=NULL) + *pAdvf = this->sinkAdviseFlag; + + if (ppAdvSink!=NULL) + { + IAdviseSink_QueryInterface(this->sinkInterface, + &IID_IAdviseSink, + (void**)ppAdvSink); + } + + return S_OK; +} + +/************************************************************************ + * DataCache_GetExtent (IViewObject2) + * + * This method retrieves the "natural" size of this cached object. + * + * See Windows documentation for more details on IViewObject2 methods. + */ +static HRESULT WINAPI DataCache_GetExtent( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + DVTARGETDEVICE* ptd, + LPSIZEL lpsizel) +{ + PresentationDataHeader presData; + HRESULT hres = E_FAIL; + + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + Print(MAX_TRACE, ("(%p, %lx, %ld, %p, %p)\n", + iface, dwDrawAspect, lindex, ptd, lpsizel)); + + /* + * Sanity check + */ + if (lpsizel==NULL) + return E_POINTER; + + /* + * Initialize the out parameter. + */ + lpsizel->cx = 0; + lpsizel->cy = 0; + + /* + * This flag should be set to -1. + */ + if (lindex!=-1) + Print(MIN_TRACE, ("Unimplemented flag lindex = %ld\n", lindex)); + + /* + * Right now, we suport only the callback from + * the default handler. + */ + if (ptd!=NULL) + Print(MIN_TRACE, ("Unimplemented ptd = %p\n", ptd)); + + /* + * Get the presentation information from the + * cache. + */ + hres = DataCache_ReadPresentationData(this, + dwDrawAspect, + &presData); + + if (SUCCEEDED(hres)) + { + lpsizel->cx = presData.dwObjectExtentX; + lpsizel->cy = presData.dwObjectExtentY; + } + + /* + * This method returns OLE_E_BLANK when it fails. + */ + if (FAILED(hres)) + hres = OLE_E_BLANK; + + return hres; +} + + +/********************************************************* + * Method implementation for the IOleCache2 + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IOleCache2_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IOleCache2_QueryInterface( + IOleCache2* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IOleCache2(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IOleCache2_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IOleCache2_AddRef( + IOleCache2* iface) +{ + _ICOM_THIS_From_IOleCache2(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IOleCache2_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IOleCache2_Release( + IOleCache2* iface) +{ + _ICOM_THIS_From_IOleCache2(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +static HRESULT WINAPI DataCache_Cache( + IOleCache2* iface, + FORMATETC* pformatetc, + DWORD advf, + DWORD* pdwConnection) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_Uncache( + IOleCache2* iface, + DWORD dwConnection) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_EnumCache( + IOleCache2* iface, + IEnumSTATDATA** ppenumSTATDATA) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_InitCache( + IOleCache2* iface, + IDataObject* pDataObject) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_IOleCache2_SetData( + IOleCache2* iface, + FORMATETC* pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_UpdateCache( + IOleCache2* iface, + LPDATAOBJECT pDataObject, + DWORD grfUpdf, + LPVOID pReserved) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_DiscardCache( + IOleCache2* iface, + DWORD dwDiscardOptions) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + + +/********************************************************* + * Method implementation for the IOleCacheControl + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IOleCacheControl_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface( + IOleCacheControl* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IOleCacheControl(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IOleCacheControl_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IOleCacheControl_AddRef( + IOleCacheControl* iface) +{ + _ICOM_THIS_From_IOleCacheControl(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IOleCacheControl_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IOleCacheControl_Release( + IOleCacheControl* iface) +{ + _ICOM_THIS_From_IOleCacheControl(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +static HRESULT WINAPI DataCache_OnRun( + IOleCacheControl* iface, + LPDATAOBJECT pDataObject) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_OnStop( + IOleCacheControl* iface) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + + diff --git a/reactos/lib/ole32/filemoniker.c b/reactos/lib/ole32/filemoniker.c new file mode 100644 index 00000000000..d4aeb6d87b9 --- /dev/null +++ b/reactos/lib/ole32/filemoniker.c @@ -0,0 +1,1340 @@ +/*************************************************************************************** + * FileMonikers implementation + * + * Copyright 1999 Noomen Hamza + ***************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +/* filemoniker data structure */ +typedef struct FileMonikerImpl{ + + ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/ + + /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether + * two monikers are equal. That's whay IROTData interface is implemented by monikers. + */ + ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/ + + ULONG ref; /* reference counter for this object */ + + LPOLESTR filePathName; /* path string identified by this filemoniker */ + +} FileMonikerImpl; + +/********************************************************************************/ +/* FileMoniker prototype functions : */ + +/* IUnknown prototype functions */ +static HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject); +static ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface); +static ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface); + +/* IPersist prototype functions */ +static HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID); + +/* IPersistStream prototype functions */ +static HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface); +static HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface, IStream* pStm); +static HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty); +static HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize); + +/* IMoniker prototype functions */ +static HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); +static HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); +static HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced); +static HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite); +static HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker); +static HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker); +static HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash); +static HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning); +static HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pFileTime); +static HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk); +static HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix); +static HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath); +static HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName); +static HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut); +static HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys); + +/********************************************************************************/ +/* IROTData prototype functions */ + +/* IUnknown prototype functions */ +static HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject); +static ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData* iface); +static ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface); + +/* IROTData prototype function */ +static HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData); + +/* Local function used by filemoniker implementation */ +HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName); +HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface); +int WINAPI FileMonikerImpl_DecomposePath(LPOLESTR str, LPOLESTR** tabStr); + + +/********************************************************************************/ +/* Virtual function table for the FileMonikerImpl class which include IPersist,*/ +/* IPersistStream and IMoniker functions. */ +static ICOM_VTABLE(IMoniker) VT_FileMonikerImpl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + FileMonikerImpl_QueryInterface, + FileMonikerImpl_AddRef, + FileMonikerImpl_Release, + FileMonikerImpl_GetClassID, + FileMonikerImpl_IsDirty, + FileMonikerImpl_Load, + FileMonikerImpl_Save, + FileMonikerImpl_GetSizeMax, + FileMonikerImpl_BindToObject, + FileMonikerImpl_BindToStorage, + FileMonikerImpl_Reduce, + FileMonikerImpl_ComposeWith, + FileMonikerImpl_Enum, + FileMonikerImpl_IsEqual, + FileMonikerImpl_Hash, + FileMonikerImpl_IsRunning, + FileMonikerImpl_GetTimeOfLastChange, + FileMonikerImpl_Inverse, + FileMonikerImpl_CommonPrefixWith, + FileMonikerImpl_RelativePathTo, + FileMonikerImpl_GetDisplayName, + FileMonikerImpl_ParseDisplayName, + FileMonikerImpl_IsSystemMoniker +}; + +/********************************************************************************/ +/* Virtual function table for the IROTData class. */ +static ICOM_VTABLE(IROTData) VT_ROTDataImpl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + FileMonikerROTDataImpl_QueryInterface, + FileMonikerROTDataImpl_AddRef, + FileMonikerROTDataImpl_Release, + FileMonikerROTDataImpl_GetComparaisonData +}; + +/******************************************************************************* + * FileMoniker_QueryInterface + *******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject) +{ + ICOM_THIS(FileMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,riid,ppvObject)); + + /* Perform a sanity check on the parameters.*/ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* Initialize the return parameter */ + *ppvObject = 0; + + /* Compare the riid with the interface IDs implemented by this object.*/ + if (IsEqualIID(&IID_IUnknown, riid) || + IsEqualIID(&IID_IPersist, riid) || + IsEqualIID(&IID_IPersistStream,riid) || + IsEqualIID(&IID_IMoniker, riid) + ) + *ppvObject = iface; + + else if (IsEqualIID(&IID_IROTData, riid)) + *ppvObject = (IROTData*)&(This->lpvtbl2); + + /* Check that we obtained an interface.*/ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* Query Interface always increases the reference count by one when it is successful */ + FileMonikerImpl_AddRef(iface); + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_AddRef + ******************************************************************************/ +ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface) +{ + ICOM_THIS(FileMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",iface)); + + return ++(This->ref); +} + +/****************************************************************************** + * FileMoniker_Release + ******************************************************************************/ +ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface) +{ + ICOM_THIS(FileMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",iface)); + + This->ref--; + + /* destroy the object if there's no more reference on it */ + if (This->ref==0){ + + FileMonikerImpl_Destroy(This); + + return 0; + } + return This->ref;; +} + +/****************************************************************************** + * FileMoniker_GetClassID + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface, + CLSID *pClassID)/* Pointer to CLSID of object */ +{ + Print(MAX_TRACE, ("(%p,%p),stub!\n",iface,pClassID)); + + if (pClassID==NULL) + return E_POINTER; + + *pClassID = CLSID_FileMoniker; + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_IsDirty + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface) +{ + /* Note that the OLE-provided implementations of the IPersistStream::IsDirty + method in the OLE-provided moniker interfaces always return S_FALSE because + their internal state never changes. */ + + Print(MAX_TRACE, ("(%p)\n",iface)); + + return S_FALSE; +} + +/****************************************************************************** + * FileMoniker_Load + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm) +{ + HRESULT res; + CHAR* filePathA; + WCHAR* filePathW; + ULONG bread; + WORD wbuffer; + DWORD dwbuffer,length,i,doubleLenHex,doubleLenDec; + + ICOM_THIS(FileMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p,%p)\n",iface,pStm)); + + /* this function locates and reads from the stream the filePath string written by FileMonikerImpl_Save */ + + /* first WORD is non significative */ + res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread); + if (bread!=sizeof(WORD) || wbuffer!=0) + return E_FAIL; + + /* read filePath string length (plus one) */ + res=IStream_Read(pStm,&length,sizeof(DWORD),&bread); + if (bread != sizeof(DWORD)) + return E_FAIL; + + /* read filePath string */ + filePathA=HeapAlloc(GetProcessHeap(),0,length); + res=IStream_Read(pStm,filePathA,length,&bread); + if (bread != length) + return E_FAIL; + + /* read the first constant */ + IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread); + if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF) + return E_FAIL; + + length--; + + for(i=0;i<10;i++){ + res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread); + if (bread!=sizeof(WORD) || wbuffer!=0) + return E_FAIL; + } + + if (length>8) + length=0; + + doubleLenHex=doubleLenDec=2*length; + if (length > 5) + doubleLenDec+=6; + + res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread); + if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenDec) + return E_FAIL; + + if (length==0) + return res; + + res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread); + if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenHex) + return E_FAIL; + + res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread); + if (bread!=sizeof(WORD) || wbuffer!=0x3) + return E_FAIL; + + filePathW=HeapAlloc(GetProcessHeap(),0,(length+1)*sizeof(WCHAR)); + filePathW[length]=0; + res=IStream_Read(pStm,filePathW,doubleLenHex,&bread); + if (bread!=doubleLenHex) + return E_FAIL; + + if (This->filePathName!=NULL) + HeapFree(GetProcessHeap(),0,This->filePathName); + + This->filePathName=filePathW; + + HeapFree(GetProcessHeap(),0,filePathA); + + return res; +} + +/****************************************************************************** + * FileMoniker_Save + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface, + IStream* pStm,/* pointer to the stream where the object is to be saved */ + BOOL fClearDirty)/* Specifies whether to clear the dirty flag */ +{ + /* this function saves data of this object. In the begining I thougth that I have just to write + * the filePath string on Stream. But, when I tested this function whith windows programs samples ! + * I noted that it was not the case. So I analysed data written by this function on Windows system and + * what did this function do exactly ! but I have no idear a bout its logic ! + * I guessed data who must be written on stream wich is: + * 1) WORD constant:zero 2) length of the path string ("\0" included) 3) path string type A + * 4) DWORD constant : 0xDEADFFFF 5) ten WORD constant: zero 6) DWORD: double-length of the the path + * string type W ("\0" not included) 7) WORD constant: 0x3 8) filePath unicode string. + * if the length(filePath) > 8 or.length(filePath) == 8 stop at step 5) + */ + + ICOM_THIS(FileMonikerImpl,iface); + + HRESULT res; + LPOLESTR filePathW=This->filePathName; + CHAR* filePathA; + DWORD len; + + DWORD constant1 = 0xDEADFFFF; /* these constants are detected after analysing the data structure written by */ + WORD constant2 = 0x3; /* FileMoniker_Save function in a windows program system */ + + WORD zero=0; + DWORD doubleLenHex; + DWORD doubleLenDec; + int i=0; + + Print(MAX_TRACE, ("(%p,%p,%d)\n",iface,pStm,fClearDirty)); + + if (pStm==NULL) + return E_POINTER; + + /* write a DWORD set to 0 : constant */ + res=IStream_Write(pStm,&zero,sizeof(WORD),NULL); + + /* write length of filePath string ( "\0" included )*/ + len = WideCharToMultiByte( CP_ACP, 0, filePathW, -1, NULL, 0, NULL, NULL ); + res=IStream_Write(pStm,&len,sizeof(DWORD),NULL); + + /* write filePath string type A */ + filePathA=HeapAlloc(GetProcessHeap(),0,len); + WideCharToMultiByte( CP_ACP, 0, filePathW, -1, filePathA, len, NULL, NULL ); + res=IStream_Write(pStm,filePathA,len,NULL); + HeapFree(GetProcessHeap(),0,filePathA); + + /* write a DWORD set to 0xDEADFFFF: constant */ + res=IStream_Write(pStm,&constant1,sizeof(DWORD),NULL); + + len--; + /* write 10 times a DWORD set to 0 : constants */ + for(i=0;i<10;i++) + res=IStream_Write(pStm,&zero,sizeof(WORD),NULL); + + if (len>8) + len=0; + + doubleLenHex=doubleLenDec=2*len; + if (len > 5) + doubleLenDec+=6; + + /* write double-length of the path string ( "\0" included )*/ + res=IStream_Write(pStm,&doubleLenDec,sizeof(DWORD),NULL); + + if (len==0) + return res; + + /* write double-length (hexa representation) of the path string ( "\0" included ) */ + res=IStream_Write(pStm,&doubleLenHex,sizeof(DWORD),NULL); + + /* write a WORD set to 0x3: constant */ + res=IStream_Write(pStm,&constant2,sizeof(WORD),NULL); + + /* write path unicode string */ + res=IStream_Write(pStm,filePathW,doubleLenHex,NULL); + + return res; +} + +/****************************************************************************** + * FileMoniker_GetSizeMax + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface, + ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */ +{ + ICOM_THIS(FileMonikerImpl,iface); + DWORD len=lstrlenW(This->filePathName); + DWORD sizeMAx; + + Print(MAX_TRACE, ("(%p,%p)\n",iface,pcbSize)); + + if (pcbSize!=NULL) + return E_POINTER; + + /* for more details see FileMonikerImpl_Save coments */ + + sizeMAx = sizeof(WORD) + /* first WORD is 0 */ + sizeof(DWORD)+ /* length of filePath including "\0" in the end of the string */ + (len+1)+ /* filePath string */ + sizeof(DWORD)+ /* constant : 0xDEADFFFF */ + 10*sizeof(WORD)+ /* 10 zero WORD */ + sizeof(DWORD); /* size of the unicode filePath: "\0" not included */ + + if (len==0 || len > 8) + return S_OK; + + sizeMAx += sizeof(DWORD)+ /* size of the unicode filePath: "\0" not included */ + sizeof(WORD)+ /* constant : 0x3 */ + len*sizeof(WCHAR); /* unicde filePath string */ + + pcbSize->u.LowPart=sizeMAx; + pcbSize->u.HighPart=0; + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_Construct (local function) + *******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPathName) +{ + int nb=0,i; + int sizeStr=lstrlenW(lpszPathName); + LPOLESTR *tabStr=0; + WCHAR twoPoint[]={'.','.',0}; + WCHAR bkSlash[]={'\\',0}; + BYTE addBkSlash; + + Print(MAX_TRACE, ("(%p,%p)\n",This,lpszPathName)); + + /* Initialize the virtual fgunction table. */ + This->lpvtbl1 = &VT_FileMonikerImpl; + This->lpvtbl2 = &VT_ROTDataImpl; + This->ref = 0; + + This->filePathName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr+1)); + + if (This->filePathName==NULL) + return E_OUTOFMEMORY; + + lstrcpyW(This->filePathName,lpszPathName); + + nb=FileMonikerImpl_DecomposePath(This->filePathName,&tabStr); + + if (nb > 0 ){ + + addBkSlash=1; + if (lstrcmpW(tabStr[0],twoPoint)!=0) + addBkSlash=0; + else + for(i=0;ifilePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR)); + + *This->filePathName=0; + + for(i=0;tabStr[i]!=NULL;i++) + lstrcatW(This->filePathName,tabStr[i]); + + if (addBkSlash) + lstrcatW(This->filePathName,bkSlash); + } + + for(i=0; tabStr[i]!=NULL;i++) + CoTaskMemFree(tabStr[i]); + CoTaskMemFree(tabStr); + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_Destroy (local function) + *******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This) +{ + Print(MAX_TRACE, ("(%p)\n",This)); + + if (This->filePathName!=NULL) + HeapFree(GetProcessHeap(),0,This->filePathName); + + HeapFree(GetProcessHeap(),0,This); + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_BindToObject + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvResult) +{ + HRESULT res=E_FAIL; + CLSID clsID; + IUnknown* pObj=0; + IRunningObjectTable *prot=0; + IPersistFile *ppf=0; + IClassFactory *pcf=0; + IClassActivator *pca=0; + + ICOM_THIS(FileMonikerImpl,iface); + + *ppvResult=0; + + Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult)); + + if(pmkToLeft==NULL){ + + res=IBindCtx_GetRunningObjectTable(pbc,&prot); + + if (SUCCEEDED(res)){ + /* if the requested class was loaded befor ! we dont need to reload it */ + res = IRunningObjectTable_GetObject(prot,iface,&pObj); + + if (res==S_FALSE){ + /* first activation of this class */ + res=GetClassFile(This->filePathName,&clsID); + if (SUCCEEDED(res)){ + + res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IPersistFile,(void**)&ppf); + if (SUCCEEDED(res)){ + + res=IPersistFile_Load(ppf,This->filePathName,STGM_READ); + if (SUCCEEDED(res)){ + + pObj=(IUnknown*)ppf; + IUnknown_AddRef(pObj); + } + } + } + } + } + } + else{ + res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassFactory,(void**)&pcf); + + if (res==E_NOINTERFACE){ + + res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassActivator,(void**)&pca); + + if (res==E_NOINTERFACE) + return MK_E_INTERMEDIATEINTERFACENOTSUPPORTED; + } + if (pcf!=NULL){ + + IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)ppf); + + res=IPersistFile_Load(ppf,This->filePathName,STGM_READ); + + if (SUCCEEDED(res)){ + + pObj=(IUnknown*)ppf; + IUnknown_AddRef(pObj); + } + } + if (pca!=NULL){ + + Print(MIN_TRACE, ("()\n")); + + /*res=GetClassFile(This->filePathName,&clsID); + + if (SUCCEEDED(res)){ + + res=IClassActivator_GetClassObject(pca,&clsID,CLSCTX_ALL,0,&IID_IPersistFile,(void**)&ppf); + + if (SUCCEEDED(res)){ + + pObj=(IUnknown*)ppf; + IUnknown_AddRef(pObj); + } + }*/ + } + } + + if (pObj!=NULL){ + /* get the requested interface from the loaded class */ + res= IUnknown_QueryInterface(pObj,riid,ppvResult); + + IBindCtx_RegisterObjectBound(pbc,(IUnknown*)*ppvResult); + + IUnknown_Release(pObj); + } + + if (prot!=NULL) + IRunningObjectTable_Release(prot); + + if (ppf!=NULL) + IPersistFile_Release(ppf); + + if (pca!=NULL) + IClassActivator_Release(pca); + + if (pcf!=NULL) + IClassFactory_Release(pcf); + + return res; +} + +/****************************************************************************** + * FileMoniker_BindToStorage + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvObject) +{ + LPOLESTR filePath=0; + IStorage *pstg=0; + HRESULT res; + + Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject)); + + if (pmkToLeft==NULL){ + + if (IsEqualIID(&IID_IStorage, riid)){ + + /* get the file name */ + FileMonikerImpl_GetDisplayName(iface,pbc,pmkToLeft,&filePath); + + /* verifie if the file contains a storage object */ + res=StgIsStorageFile(filePath); + + if(res==S_OK){ + + res=StgOpenStorage(filePath,NULL,STGM_READWRITE|STGM_SHARE_DENY_WRITE,NULL,0,&pstg); + + if (SUCCEEDED(res)){ + + *ppvObject=pstg; + + IStorage_AddRef(pstg); + + return res; + } + } + CoTaskMemFree(filePath); + } + else + if ( (IsEqualIID(&IID_IStream, riid)) || (IsEqualIID(&IID_ILockBytes, riid)) ) + + return E_UNSPEC; + else + + return E_NOINTERFACE; + } + else { + + Print(MIN_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject)); + + return E_NOTIMPL; +} + return res; +} + +/****************************************************************************** + * FileMoniker_Reduce + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface, + IBindCtx* pbc, + DWORD dwReduceHowFar, + IMoniker** ppmkToLeft, + IMoniker** ppmkReduced) +{ + Print(MAX_TRACE, ("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced)); + + if (ppmkReduced==NULL) + return E_POINTER; + + FileMonikerImpl_AddRef(iface); + + *ppmkReduced=iface; + + return MK_S_REDUCED_TO_SELF; +} +/****************************************************************************** + * FileMoniker_ComposeWith + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface, + IMoniker* pmkRight, + BOOL fOnlyIfNotGeneric, + IMoniker** ppmkComposite) +{ + HRESULT res; + LPOLESTR str1=0,str2=0,*strDec1=0,*strDec2=0,newStr=0; + WCHAR twoPoint[]={'.','.',0}; + WCHAR bkSlash[]={'\\',0}; + IBindCtx *bind=0; + int i=0,j=0,lastIdx1=0,lastIdx2=0; + DWORD mkSys; + + Print(MAX_TRACE, ("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite)); + + if (ppmkComposite==NULL) + return E_POINTER; + + if (pmkRight==NULL) + return E_INVALIDARG; + + *ppmkComposite=0; + + IMoniker_IsSystemMoniker(pmkRight,&mkSys); + + /* check if we have two filemonikers to compose or not */ + if(mkSys==MKSYS_FILEMONIKER){ + + CreateBindCtx(0,&bind); + + FileMonikerImpl_GetDisplayName(iface,bind,NULL,&str1); + IMoniker_GetDisplayName(pmkRight,bind,NULL,&str2); + + /* decompose pathnames of the two monikers : (to prepare the path merge operation ) */ + lastIdx1=FileMonikerImpl_DecomposePath(str1,&strDec1)-1; + lastIdx2=FileMonikerImpl_DecomposePath(str2,&strDec2)-1; + + if ((lastIdx1==-1 && lastIdx2>-1)||(lastIdx1==1 && lstrcmpW(strDec1[0],twoPoint)==0)) + return MK_E_SYNTAX; + + if(lstrcmpW(strDec1[lastIdx1],bkSlash)==0) + lastIdx1--; + + /* for etch "..\" in the left of str2 remove the right element from str1 */ + for(i=0; ( (lastIdx1>=0) && (strDec2[i]!=NULL) && (lstrcmpW(strDec2[i],twoPoint)==0) ) ;i+=2){ + + lastIdx1-=2; + } + + /* the length of the composed path string is raised by the sum of the two paths lengths */ + newStr=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(lstrlenW(str1)+lstrlenW(str2)+1)); + + if (newStr==NULL) + return E_OUTOFMEMORY; + + /* new path is the concatenation of the rest of str1 and str2 */ + for(*newStr=0,j=0;j<=lastIdx1;j++) + lstrcatW(newStr,strDec1[j]); + + if ((strDec2[i]==NULL && lastIdx1>-1 && lastIdx2>-1) || lstrcmpW(strDec2[i],bkSlash)!=0) + lstrcatW(newStr,bkSlash); + + for(j=i;j<=lastIdx2;j++) + lstrcatW(newStr,strDec2[j]); + + /* create a new moniker with the new string */ + res=CreateFileMoniker(newStr,ppmkComposite); + + /* free all strings space memory used by this function */ + HeapFree(GetProcessHeap(),0,newStr); + + for(i=0; strDec1[i]!=NULL;i++) + CoTaskMemFree(strDec1[i]); + for(i=0; strDec2[i]!=NULL;i++) + CoTaskMemFree(strDec2[i]); + CoTaskMemFree(strDec1); + CoTaskMemFree(strDec2); + + CoTaskMemFree(str1); + CoTaskMemFree(str2); + + return res; + } + else if(mkSys==MKSYS_ANTIMONIKER){ + + *ppmkComposite=NULL; + return S_OK; + } + else if (fOnlyIfNotGeneric){ + + *ppmkComposite=NULL; + return MK_E_NEEDGENERIC; + } + else + + return CreateGenericComposite(iface,pmkRight,ppmkComposite); +} + +/****************************************************************************** + * FileMoniker_Enum + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) +{ + Print(MAX_TRACE, ("(%p,%d,%p)\n",iface,fForward,ppenumMoniker)); + + if (ppenumMoniker == NULL) + return E_POINTER; + + *ppenumMoniker = NULL; + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_IsEqual + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) +{ + ICOM_THIS(FileMonikerImpl,iface); + CLSID clsid; + LPOLESTR filePath; + IBindCtx* bind; + HRESULT res; + + Print(MAX_TRACE, ("(%p,%p)\n",iface,pmkOtherMoniker)); + + if (pmkOtherMoniker==NULL) + return S_FALSE; + + IMoniker_GetClassID(pmkOtherMoniker,&clsid); + + if (!IsEqualCLSID(&clsid,&CLSID_FileMoniker)) + + return S_FALSE; + + res=CreateBindCtx(0,&bind); + if (FAILED(res)) + return res; + + IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&filePath); + + if (lstrcmpiW(filePath, + This->filePathName)!=0) + + return S_FALSE; + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_Hash + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) +{ + ICOM_THIS(FileMonikerImpl,iface); + + int h = 0,i,skip,len; + int off = 0; + LPOLESTR val; + + if (pdwHash==NULL) + return E_POINTER; + + val = This->filePathName; + len = lstrlenW(val); + + if (len < 16) { + for (i = len ; i > 0; i--) { + h = (h * 37) + val[off++]; + } + } else { + /* only sample some characters */ + skip = len / 8; + for (i = len ; i > 0; i -= skip, off += skip) { + h = (h * 39) + val[off]; + } +} + + *pdwHash=h; + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_IsRunning + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + IMoniker* pmkNewlyRunning) +{ + IRunningObjectTable* rot; + HRESULT res; + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning)); + + if ( (pmkNewlyRunning!=NULL) && (IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK) ) + return S_OK; + + if (pbc==NULL) + return E_POINTER; + + res=IBindCtx_GetRunningObjectTable(pbc,&rot); + + if (FAILED(res)) + return res; + + res = IRunningObjectTable_IsRunning(rot,iface); + + IRunningObjectTable_Release(rot); + + return res; +} + +/****************************************************************************** + * FileMoniker_GetTimeOfLastChange + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + FILETIME* pFileTime) +{ + ICOM_THIS(FileMonikerImpl,iface); + IRunningObjectTable* rot; + HRESULT res; + WIN32_FILE_ATTRIBUTE_DATA info; + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pFileTime)); + + if (pFileTime==NULL) + return E_POINTER; + + if (pmkToLeft!=NULL) + return E_INVALIDARG; + + res=IBindCtx_GetRunningObjectTable(pbc,&rot); + + if (FAILED(res)) + return res; + + res= IRunningObjectTable_GetTimeOfLastChange(rot,iface,pFileTime); + + if (FAILED(res)){ /* the moniker is not registred */ +#if 0 + if (!GetFileAttributesExW(This->filePathName,GetFileExInfoStandard,&info)) + return MK_E_NOOBJECT; +#else + Print(MIN_TRACE, ("GetFileAttributesExW() nowhere to be found\n")); +#endif + *pFileTime=info.ftLastWriteTime; +} + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_Inverse + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) +{ + + Print(MAX_TRACE, ("(%p,%p)\n",iface,ppmk)); + + return CreateAntiMoniker(ppmk); +} + +/****************************************************************************** + * FileMoniker_CommonPrefixWith + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) +{ + + LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath; + IBindCtx *pbind; + DWORD mkSys; + ULONG nb1,nb2,i,sameIdx; + BOOL machimeNameCase=FALSE; + + if (ppmkPrefix==NULL) + return E_POINTER; + + if (pmkOther==NULL) + return E_INVALIDARG; + + *ppmkPrefix=0; + + /* check if we have the same type of moniker */ + IMoniker_IsSystemMoniker(pmkOther,&mkSys); + + if(mkSys==MKSYS_FILEMONIKER){ + + CreateBindCtx(0,&pbind); + + /* create a string based on common part of the two paths */ + + IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis); + IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther); + + nb1=FileMonikerImpl_DecomposePath(pathThis,&stringTable1); + nb2=FileMonikerImpl_DecomposePath(pathOther,&stringTable2); + + if (nb1==0 || nb2==0) + return MK_E_NOPREFIX; + + commonPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1)); + + *commonPath=0; + + for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) && + (stringTable2[sameIdx]!=NULL) && + (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++); + + if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){ + + machimeNameCase=TRUE; + + for(i=2;i 3 || nb2 > 3) ) + return MK_E_NOPREFIX; + + for(i=0;i0 && !(len1==1 && len2==1 && sameIdx==0)) + for(j=sameIdx;(tabStr1[j] != NULL); j++) + if (*tabStr1[j]!='\\') + lstrcatW(relPath,back); + + /* add items of the second path (similar items with the first path are not included) to the relativePath */ + for(j=sameIdx;tabStr2[j]!=NULL;j++) + lstrcatW(relPath,tabStr2[j]); + + res=CreateFileMoniker(relPath,ppmkRelPath); + + for(j=0; tabStr1[j]!=NULL;j++) + CoTaskMemFree(tabStr1[j]); + for(j=0; tabStr2[j]!=NULL;j++) + CoTaskMemFree(tabStr2[j]); + CoTaskMemFree(tabStr1); + CoTaskMemFree(tabStr2); + CoTaskMemFree(str1); + CoTaskMemFree(str2); + HeapFree(GetProcessHeap(),0,relPath); + + if (len1==0 || len2==0 || (len1==1 && len2==1 && sameIdx==0)) + return MK_S_HIM; + + return res; +} + +/****************************************************************************** + * FileMoniker_GetDisplayName + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + LPOLESTR *ppszDisplayName) +{ + ICOM_THIS(FileMonikerImpl,iface); + + int len=lstrlenW(This->filePathName); + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName)); + + if (ppszDisplayName==NULL) + return E_POINTER; + + if (pmkToLeft!=NULL) + return E_INVALIDARG; + + *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(len+1)); + if (*ppszDisplayName==NULL) + return E_OUTOFMEMORY; + + lstrcpyW(*ppszDisplayName,This->filePathName); + + return S_OK; +} + +/****************************************************************************** + * FileMoniker_ParseDisplayName + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + LPOLESTR pszDisplayName, + ULONG* pchEaten, + IMoniker** ppmkOut) +{ + Print(MIN_TRACE, ("(%p,%p,%p,%p,%p,%p),stub!\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut)); + return E_NOTIMPL; +} + +/****************************************************************************** + * FileMoniker_IsSystemMoniker + ******************************************************************************/ +HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys) +{ + Print(MAX_TRACE, ("(%p,%p)\n",iface,pwdMksys)); + + if (!pwdMksys) + return E_POINTER; + + (*pwdMksys)=MKSYS_FILEMONIKER; + + return S_OK; +} + +/******************************************************************************* + * FileMonikerIROTData_QueryInterface + *******************************************************************************/ +HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject) +{ + + ICOM_THIS_From_IROTData(IMoniker, iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,riid,ppvObject)); + + return FileMonikerImpl_QueryInterface(This, riid, ppvObject); +} + +/*********************************************************************** + * FileMonikerIROTData_AddRef + */ +ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData *iface) +{ + ICOM_THIS_From_IROTData(IMoniker, iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + return FileMonikerImpl_AddRef(This); +} + +/*********************************************************************** + * FileMonikerIROTData_Release + */ +ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface) +{ + ICOM_THIS_From_IROTData(IMoniker, iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + return FileMonikerImpl_Release(This); +} + +/****************************************************************************** + * FileMonikerIROTData_GetComparaisonData + ******************************************************************************/ +HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface, + BYTE* pbData, + ULONG cbMax, + ULONG* pcbData) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/****************************************************************************** + * CreateFileMoniker16 + ******************************************************************************/ +HRESULT WINAPI CreateFileMoniker16(LPCOLESTR16 lpszPathName,LPMONIKER* ppmk) +{ + + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/****************************************************************************** + * CreateFileMoniker + ******************************************************************************/ +HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk) +{ + FileMonikerImpl* newFileMoniker = 0; + HRESULT hr = E_FAIL; + IID riid=IID_IMoniker; + + Print(MAX_TRACE, ("(%p,%p)\n",lpszPathName,ppmk)); + + if (ppmk==NULL) + return E_POINTER; + + if(lpszPathName==NULL) + return MK_E_SYNTAX; + + *ppmk=0; + + newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl)); + + if (newFileMoniker == 0) + return E_OUTOFMEMORY; + + hr = FileMonikerImpl_Construct(newFileMoniker,lpszPathName); + + if (SUCCEEDED(hr)) + hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&riid,(void**)ppmk); + else + HeapFree(GetProcessHeap(),0,newFileMoniker); + + return hr; +} diff --git a/reactos/lib/ole32/itemmoniker.c b/reactos/lib/ole32/itemmoniker.c new file mode 100644 index 00000000000..01e7e138054 --- /dev/null +++ b/reactos/lib/ole32/itemmoniker.c @@ -0,0 +1,973 @@ +/*************************************************************************************** + * ItemMonikers implementation + * + * Copyright 1999 Noomen Hamza + ***************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + + +/* ItemMoniker data structure */ +typedef struct ItemMonikerImpl{ + + ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/ + + /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether + * two monikers are equal. That's whay IROTData interface is implemented by monikers. + */ + ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/ + + ULONG ref; /* reference counter for this object */ + + LPOLESTR itemName; /* item name identified by this ItemMoniker */ + + LPOLESTR itemDelimiter; /* Delimiter string */ + +} ItemMonikerImpl; + +/********************************************************************************/ +/* ItemMoniker prototype functions : */ + +/* IUnknown prototype functions */ +static HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject); +static ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface); +static ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface); + +/* IPersist prototype functions */ +static HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID); + +/* IPersistStream prototype functions */ +static HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface); +static HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface, IStream* pStm); +static HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty); +static HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize); + +/* IMoniker prototype functions */ +static HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); +static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult); +static HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced); +static HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite); +static HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker); +static HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker); +static HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash); +static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning); +static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime); +static HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk); +static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix); +static HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath); +static HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName); +static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut); +static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys); + +/* Local function used by ItemMoniker implementation */ +HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName); +HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface); + +/********************************************************************************/ +/* IROTData prototype functions */ + +/* IUnknown prototype functions */ +static HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject); +static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface); +static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface); + +/* IROTData prototype function */ +static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData); + +/********************************************************************************/ +/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/ +/* IPersistStream and IMoniker functions. */ +static ICOM_VTABLE(IMoniker) VT_ItemMonikerImpl = + { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + ItemMonikerImpl_QueryInterface, + ItemMonikerImpl_AddRef, + ItemMonikerImpl_Release, + ItemMonikerImpl_GetClassID, + ItemMonikerImpl_IsDirty, + ItemMonikerImpl_Load, + ItemMonikerImpl_Save, + ItemMonikerImpl_GetSizeMax, + ItemMonikerImpl_BindToObject, + ItemMonikerImpl_BindToStorage, + ItemMonikerImpl_Reduce, + ItemMonikerImpl_ComposeWith, + ItemMonikerImpl_Enum, + ItemMonikerImpl_IsEqual, + ItemMonikerImpl_Hash, + ItemMonikerImpl_IsRunning, + ItemMonikerImpl_GetTimeOfLastChange, + ItemMonikerImpl_Inverse, + ItemMonikerImpl_CommonPrefixWith, + ItemMonikerImpl_RelativePathTo, + ItemMonikerImpl_GetDisplayName, + ItemMonikerImpl_ParseDisplayName, + ItemMonikerImpl_IsSystemMoniker +}; + +/********************************************************************************/ +/* Virtual function table for the IROTData class. */ +static ICOM_VTABLE(IROTData) VT_ROTDataImpl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + ItemMonikerROTDataImpl_QueryInterface, + ItemMonikerROTDataImpl_AddRef, + ItemMonikerROTDataImpl_Release, + ItemMonikerROTDataImpl_GetComparaisonData +}; + +/******************************************************************************* + * ItemMoniker_QueryInterface + *******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject) +{ + ICOM_THIS(ItemMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,riid,ppvObject)); + + /* Perform a sanity check on the parameters.*/ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* Initialize the return parameter */ + *ppvObject = 0; + + /* Compare the riid with the interface IDs implemented by this object.*/ + if (IsEqualIID(&IID_IUnknown, riid) || + IsEqualIID(&IID_IPersist, riid) || + IsEqualIID(&IID_IPersistStream, riid) || + IsEqualIID(&IID_IMoniker, riid) + ) + *ppvObject = iface; + + else if (IsEqualIID(&IID_IROTData, riid)) + *ppvObject = (IROTData*)&(This->lpvtbl2); + + /* Check that we obtained an interface.*/ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* Query Interface always increases the reference count by one when it is successful */ + ItemMonikerImpl_AddRef(iface); + + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_AddRef + ******************************************************************************/ +ULONG WINAPI ItemMonikerImpl_AddRef(IMoniker* iface) +{ + ICOM_THIS(ItemMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + return ++(This->ref); +} + +/****************************************************************************** + * ItemMoniker_Release + ******************************************************************************/ +ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface) +{ + ICOM_THIS(ItemMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + This->ref--; + + /* destroy the object if there's no more reference on it */ + if (This->ref==0){ + + ItemMonikerImpl_Destroy(This); + + return 0; + } + return This->ref;; +} + +/****************************************************************************** + * ItemMoniker_GetClassID + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID) +{ + Print(MAX_TRACE, ("(%p,%p),stub!\n",iface,pClassID)); + + if (pClassID==NULL) + return E_POINTER; + + *pClassID = CLSID_ItemMoniker; + + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_IsDirty + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_IsDirty(IMoniker* iface) +{ + /* Note that the OLE-provided implementations of the IPersistStream::IsDirty + method in the OLE-provided moniker interfaces always return S_FALSE because + their internal state never changes. */ + + Print(MAX_TRACE, ("(%p)\n",iface)); + + return S_FALSE; +} + +/****************************************************************************** + * ItemMoniker_Load + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm) +{ + + ICOM_THIS(ItemMonikerImpl,iface); + HRESULT res; + DWORD delimiterLength,nameLength,lenW; + CHAR *itemNameA,*itemDelimiterA; + ULONG bread; + + /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */ + + /* read item delimiter string length + 1 */ + res=IStream_Read(pStm,&delimiterLength,sizeof(DWORD),&bread); + if (bread != sizeof(DWORD)) + return E_FAIL; + + /* read item delimiter string */ + if (!(itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength))) + return E_OUTOFMEMORY; + res=IStream_Read(pStm,itemDelimiterA,delimiterLength,&bread); + if (bread != delimiterLength) + { + HeapFree( GetProcessHeap(), 0, itemDelimiterA ); + return E_FAIL; + } + + lenW = MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, NULL, 0 ); + This->itemDelimiter=HeapReAlloc(GetProcessHeap(),0,This->itemDelimiter,lenW*sizeof(WCHAR)); + if (!This->itemDelimiter) + { + HeapFree( GetProcessHeap(), 0, itemDelimiterA ); + return E_OUTOFMEMORY; + } + MultiByteToWideChar( CP_ACP, 0, itemDelimiterA, -1, This->itemDelimiter, lenW ); + HeapFree( GetProcessHeap(), 0, itemDelimiterA ); + + /* read item name string length + 1*/ + res=IStream_Read(pStm,&nameLength,sizeof(DWORD),&bread); + if (bread != sizeof(DWORD)) + return E_FAIL; + + /* read item name string */ + if (!(itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength))) + return E_OUTOFMEMORY; + res=IStream_Read(pStm,itemNameA,nameLength,&bread); + if (bread != nameLength) + { + HeapFree( GetProcessHeap(), 0, itemNameA ); + return E_FAIL; + } + + lenW = MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, NULL, 0 ); + This->itemName=HeapReAlloc(GetProcessHeap(),0,This->itemName,lenW*sizeof(WCHAR)); + if (!This->itemName) + { + HeapFree( GetProcessHeap(), 0, itemNameA ); + return E_OUTOFMEMORY; + } + MultiByteToWideChar( CP_ACP, 0, itemNameA, -1, This->itemName, lenW ); + HeapFree( GetProcessHeap(), 0, itemNameA ); + + return res; +} + +/****************************************************************************** + * ItemMoniker_Save + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface, + IStream* pStm,/* pointer to the stream where the object is to be saved */ + BOOL fClearDirty)/* Specifies whether to clear the dirty flag */ +{ + ICOM_THIS(ItemMonikerImpl,iface); + HRESULT res; + CHAR *itemNameA,*itemDelimiterA; + + /* data writen by this function are : 1) DWORD : size of item delimiter string ('\0' included ) */ + /* 2) String (type A): item delimiter string ('\0' included) */ + /* 3) DWORD : size of item name string ('\0' included) */ + /* 4) String (type A): item name string ('\0' included) */ + + DWORD nameLength = WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, NULL, 0, NULL, NULL); + DWORD delimiterLength = WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, NULL, 0, NULL, NULL); + itemNameA=HeapAlloc(GetProcessHeap(),0,nameLength); + itemDelimiterA=HeapAlloc(GetProcessHeap(),0,delimiterLength); + WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL); + WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL); + + res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL); + res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL); + res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL); + res=IStream_Write(pStm,itemNameA,nameLength * sizeof(CHAR),NULL); + + return res; +} + +/****************************************************************************** + * ItemMoniker_GetSizeMax + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface, + ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */ +{ + ICOM_THIS(ItemMonikerImpl,iface); + DWORD delimiterLength=lstrlenW(This->itemDelimiter)+1; + DWORD nameLength=lstrlenW(This->itemName)+1; + + Print(MAX_TRACE, ("(%p,%p)\n",iface,pcbSize)); + + if (pcbSize!=NULL) + return E_POINTER; + + /* for more details see ItemMonikerImpl_Save coments */ + + pcbSize->u.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */ + delimiterLength + /* item delimiter string */ + sizeof(DWORD) + /* DWORD which contains item name length */ + nameLength + /* item name string */ + 34; /* this constant was added ! because when I tested this function it usually */ + /* returns 34 bytes more than the number of bytes used by IMoniker::Save function */ + pcbSize->u.HighPart=0; + + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_Construct (local function) + *******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem) +{ + + int sizeStr1=lstrlenW(lpszItem), sizeStr2; + static const OLECHAR emptystr[1]; + LPCOLESTR delim; + + Print(MAX_TRACE, ("(%p,%p)\n",This,lpszItem)); + + /* Initialize the virtual fgunction table. */ + This->lpvtbl1 = &VT_ItemMonikerImpl; + This->lpvtbl2 = &VT_ROTDataImpl; + This->ref = 0; + + This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1)); + if (!This->itemName) + return E_OUTOFMEMORY; + lstrcpyW(This->itemName,lpszItem); + + if (!lpszDelim) + Print(MIN_TRACE, ("lpszDelim is NULL. Using empty string which is possibly wrong.\n")); + + delim = lpszDelim ? lpszDelim : emptystr; + + sizeStr2=lstrlenW(delim); + This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1)); + if (!This->itemDelimiter) { + HeapFree(GetProcessHeap(),0,This->itemName); + return E_OUTOFMEMORY; + } + lstrcpyW(This->itemDelimiter,delim); + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_Destroy (local function) + *******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This) +{ + Print(MAX_TRACE, ("(%p)\n",This)); + + if (This->itemName) + HeapFree(GetProcessHeap(),0,This->itemName); + + if (This->itemDelimiter) + HeapFree(GetProcessHeap(),0,This->itemDelimiter); + + HeapFree(GetProcessHeap(),0,This); + + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_BindToObject + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvResult) +{ + ICOM_THIS(ItemMonikerImpl,iface); + + HRESULT res; + IID refid=IID_IOleItemContainer; + IOleItemContainer *poic=0; + + Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult)); + + if(ppvResult ==NULL) + return E_POINTER; + + if(pmkToLeft==NULL) + return E_INVALIDARG; + + *ppvResult=0; + + res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&refid,(void**)&poic); + + if (SUCCEEDED(res)){ + + res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,riid,ppvResult); + + IOleItemContainer_Release(poic); + } + + return res; +} + +/****************************************************************************** + * ItemMoniker_BindToStorage + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + REFIID riid, + VOID** ppvResult) +{ + ICOM_THIS(ItemMonikerImpl,iface); + + HRESULT res; + IOleItemContainer *poic=0; + + Print(MAX_TRACE, ("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult)); + + *ppvResult=0; + + if(pmkToLeft==NULL) + return E_INVALIDARG; + + res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic); + + if (SUCCEEDED(res)){ + + res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult); + + IOleItemContainer_Release(poic); + } + + return res; +} + +/****************************************************************************** + * ItemMoniker_Reduce + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface, + IBindCtx* pbc, + DWORD dwReduceHowFar, + IMoniker** ppmkToLeft, + IMoniker** ppmkReduced) +{ + Print(MAX_TRACE, ("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced)); + + if (ppmkReduced==NULL) + return E_POINTER; + + ItemMonikerImpl_AddRef(iface); + + *ppmkReduced=iface; + + return MK_S_REDUCED_TO_SELF; +} +/****************************************************************************** + * ItemMoniker_ComposeWith + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_ComposeWith(IMoniker* iface, + IMoniker* pmkRight, + BOOL fOnlyIfNotGeneric, + IMoniker** ppmkComposite) +{ + HRESULT res=S_OK; + DWORD mkSys,mkSys2; + IEnumMoniker* penumMk=0; + IMoniker *pmostLeftMk=0; + IMoniker* tempMkComposite=0; + + Print(MAX_TRACE, ("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite)); + + if ((ppmkComposite==NULL)||(pmkRight==NULL)) + return E_POINTER; + + *ppmkComposite=0; + + IMoniker_IsSystemMoniker(pmkRight,&mkSys); + + /* If pmkRight is an anti-moniker, the returned moniker is NULL */ + if(mkSys==MKSYS_ANTIMONIKER) + return res; + + else + /* if pmkRight is a composite whose leftmost component is an anti-moniker, */ + /* the returned moniker is the composite after the leftmost anti-moniker is removed. */ + + if(mkSys==MKSYS_GENERICCOMPOSITE){ + + res=IMoniker_Enum(pmkRight,TRUE,&penumMk); + + if (FAILED(res)) + return res; + + res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL); + + IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2); + + if(mkSys2==MKSYS_ANTIMONIKER){ + + IMoniker_Release(pmostLeftMk); + + tempMkComposite=iface; + IMoniker_AddRef(iface); + + while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){ + + res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite); + + IMoniker_Release(tempMkComposite); + IMoniker_Release(pmostLeftMk); + + tempMkComposite=*ppmkComposite; + IMoniker_AddRef(tempMkComposite); +} + return res; + } + else + return CreateGenericComposite(iface,pmkRight,ppmkComposite); + } + /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic + composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns + a NULL moniker and a return value of MK_E_NEEDGENERIC */ + else + if (!fOnlyIfNotGeneric) + return CreateGenericComposite(iface,pmkRight,ppmkComposite); + + else + return MK_E_NEEDGENERIC; +} + +/****************************************************************************** + * ItemMoniker_Enum + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) +{ + Print(MAX_TRACE, ("(%p,%d,%p)\n",iface,fForward,ppenumMoniker)); + + if (ppenumMoniker == NULL) + return E_POINTER; + + *ppenumMoniker = NULL; + + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_IsEqual + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) +{ + + CLSID clsid; + LPOLESTR dispName1,dispName2; + IBindCtx* bind; + HRESULT res; + + Print(MAX_TRACE, ("(%p,%p)\n",iface,pmkOtherMoniker)); + + if (pmkOtherMoniker==NULL) + return S_FALSE; + + /* This method returns S_OK if both monikers are item monikers and their display names are */ + /* identical (using a case-insensitive comparison); otherwise, the method returns S_FALSE. */ + + IMoniker_GetClassID(pmkOtherMoniker,&clsid); + + if (!IsEqualCLSID(&clsid,&CLSID_ItemMoniker)) + return S_FALSE; + + res=CreateBindCtx(0,&bind); + if (FAILED(res)) + return res; + + IMoniker_GetDisplayName(iface,bind,NULL,&dispName1); + IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2); + + if (lstrcmpW(dispName1,dispName2)!=0) + return S_FALSE; + + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_Hash + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash) +{ + ICOM_THIS(ItemMonikerImpl,iface); + + int h = 0,i,skip,len; + int off = 0; + LPOLESTR val; + + if (pdwHash==NULL) + return E_POINTER; + + val = This->itemName; + len = lstrlenW(val); + + if (len < 16) { + for (i = len ; i > 0; i--) { + h = (h * 37) + val[off++]; +} + } else { + /* only sample some characters */ + skip = len / 8; + for (i = len ; i > 0; i -= skip, off += skip) { + h = (h * 39) + val[off]; + } + } + + *pdwHash=h; + + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_IsRunning + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + IMoniker* pmkNewlyRunning) +{ + IRunningObjectTable* rot; + HRESULT res; + IOleItemContainer *poic=0; + ICOM_THIS(ItemMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning)); + + /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */ + /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */ + if (pmkToLeft==NULL) + if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK)) + return S_OK; + else { + if (pbc==NULL) + return E_POINTER; + + res=IBindCtx_GetRunningObjectTable(pbc,&rot); + + if (FAILED(res)) + return res; + + res = IRunningObjectTable_IsRunning(rot,iface); + + IRunningObjectTable_Release(rot); + } + else{ + + /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */ + /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/ + /* passing the string contained within this moniker. */ + + res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic); + + if (SUCCEEDED(res)){ + + res=IOleItemContainer_IsRunning(poic,This->itemName); + + IOleItemContainer_Release(poic); + } + } + + return res; +} + +/****************************************************************************** + * ItemMoniker_GetTimeOfLastChange + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + FILETIME* pItemTime) +{ + IRunningObjectTable* rot; + HRESULT res; + IMoniker *compositeMk; + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime)); + + if (pItemTime==NULL) + return E_INVALIDARG; + + /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */ + if (pmkToLeft==NULL) + + return MK_E_NOTBINDABLE; + else { + + /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */ + /* the time of last change. If the object is not in the ROT, the method calls */ + /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */ + + res=CreateGenericComposite(pmkToLeft,iface,&compositeMk); + + res=IBindCtx_GetRunningObjectTable(pbc,&rot); + + if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK) + + res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime); + + IMoniker_Release(compositeMk); +} + + return res; +} + +/****************************************************************************** + * ItemMoniker_Inverse + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk) +{ + Print(MAX_TRACE, ("(%p,%p)\n",iface,ppmk)); + + if (ppmk==NULL) + return E_POINTER; + + return CreateAntiMoniker(ppmk); +} + +/****************************************************************************** + * ItemMoniker_CommonPrefixWith + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) +{ + DWORD mkSys; + IMoniker_IsSystemMoniker(pmkOther,&mkSys); + /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */ + /* to this moniker and returns MK_S_US */ + + if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){ + + *ppmkPrefix=iface; + + IMoniker_AddRef(iface); + + return MK_S_US; + } + else + /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */ + /* the case where the other moniker is a generic composite. */ + return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix); +} + +/****************************************************************************** + * ItemMoniker_RelativePathTo + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) +{ + Print(MAX_TRACE, ("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath)); + + if (ppmkRelPath==NULL) + return E_POINTER; + + *ppmkRelPath=0; + + return MK_E_NOTBINDABLE; +} + +/****************************************************************************** + * ItemMoniker_GetDisplayName + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + LPOLESTR *ppszDisplayName) +{ + ICOM_THIS(ItemMonikerImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName)); + + if (ppszDisplayName==NULL) + return E_POINTER; + + if (pmkToLeft!=NULL){ + return E_INVALIDARG; + } + + *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(lstrlenW(This->itemDelimiter)+lstrlenW(This->itemName)+1)); + + if (*ppszDisplayName==NULL) + return E_OUTOFMEMORY; + + lstrcpyW(*ppszDisplayName,This->itemDelimiter); + lstrcatW(*ppszDisplayName,This->itemName); + + return S_OK; +} + +/****************************************************************************** + * ItemMoniker_ParseDisplayName + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface, + IBindCtx* pbc, + IMoniker* pmkToLeft, + LPOLESTR pszDisplayName, + ULONG* pchEaten, + IMoniker** ppmkOut) +{ + IOleItemContainer* poic=0; + IParseDisplayName* ppdn=0; + LPOLESTR displayName; + HRESULT res; + ICOM_THIS(ItemMonikerImpl,iface); + + /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */ + if (pmkToLeft==NULL) + + return MK_E_SYNTAX; + + else{ + /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */ + /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */ /* name to IParseDisplayName::ParseDisplayName */ + res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic); + + if (SUCCEEDED(res)){ + + res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn); + + res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName); + + res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut); + + IOleItemContainer_Release(poic); + IParseDisplayName_Release(ppdn); + } +} + return res; +} + +/****************************************************************************** + * ItemMoniker_IsSystemMoniker + ******************************************************************************/ +HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys) +{ + Print(MAX_TRACE, ("(%p,%p)\n",iface,pwdMksys)); + + if (!pwdMksys) + return E_POINTER; + + (*pwdMksys)=MKSYS_ITEMMONIKER; + + return S_OK; +} + +/******************************************************************************* + * ItemMonikerIROTData_QueryInterface + *******************************************************************************/ +HRESULT WINAPI ItemMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject) +{ + + ICOM_THIS_From_IROTData(IMoniker, iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",iface,riid,ppvObject)); + + return ItemMonikerImpl_QueryInterface(This, riid, ppvObject); +} + +/*********************************************************************** + * ItemMonikerIROTData_AddRef + */ +ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData *iface) +{ + ICOM_THIS_From_IROTData(IMoniker, iface); + + Print(MAX_TRACE, ("(%p)\n",iface)); + + return ItemMonikerImpl_AddRef(This); +} + +/*********************************************************************** + * ItemMonikerIROTData_Release + */ +ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface) +{ + ICOM_THIS_From_IROTData(IMoniker, iface); + + Print(MAX_TRACE, ("(%p)\n",iface)); + + return ItemMonikerImpl_Release(This); +} + +/****************************************************************************** + * ItemMonikerIROTData_GetComparaisonData + ******************************************************************************/ +HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface, + BYTE* pbData, + ULONG cbMax, + ULONG* pcbData) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/****************************************************************************** + * CreateItemMoniker16 [OLE2.28] + ******************************************************************************/ +HRESULT WINAPI CreateItemMoniker16(LPCOLESTR16 lpszDelim,LPCOLESTR lpszItem,LPMONIKER* ppmk) +{ + + Print(MIN_TRACE, ("(%s,%p),stub!\n",lpszDelim,ppmk)); + *ppmk = NULL; + return E_NOTIMPL; +} + +/****************************************************************************** + * CreateItemMoniker [OLE.55] + ******************************************************************************/ +HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONIKER * ppmk) +{ + ItemMonikerImpl* newItemMoniker = 0; + HRESULT hr = S_OK; + IID riid=IID_IMoniker; + + Print(MAX_TRACE, ("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk)); + + newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl)); + + if (newItemMoniker == 0) + return STG_E_INSUFFICIENTMEMORY; + + hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem); + + if (FAILED(hr)){ + + HeapFree(GetProcessHeap(),0,newItemMoniker); + return hr; + } + + return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk); +} diff --git a/reactos/lib/ole32/makefile b/reactos/lib/ole32/makefile index d4c3af809fa..075d03fe3c4 100644 --- a/reactos/lib/ole32/makefile +++ b/reactos/lib/ole32/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.5 2001/08/21 20:13:07 chorns Exp $ +# $Id: makefile,v 1.6 2001/09/02 09:10:47 chorns Exp $ # # Jurgen Van Gael [jurgen.vangael@student.kuleuven.ac.be] # @@ -13,9 +13,11 @@ TARGET_NAME = ole32 TARGET_BASE = 0x77a50000 -TARGET_CFLAGS = -fno-rtti +TARGET_DEFONLY = yes -TARGET_SDKLIBS = kernel32.a +TARGET_CFLAGS = -fno-rtti -I./include + +TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a user32.a gdi32.a msvcrt.a TARGET_OBJECTS = \ DllMain.o \ @@ -24,7 +26,19 @@ TARGET_OBJECTS = \ Ole2.o \ OleAuto.o \ Misc.o \ - Storage.o + Storage.o \ + storage32.o \ + stg_stream.o \ + stg_bigblockfile.o \ + compobj.o \ + memlockbytes.o \ + rpcrt4_main.o \ + filemoniker.o \ + bindctx.o \ + compositemoniker.o \ + itemmoniker.o \ + antimoniker.o \ + datacache.o include $(PATH_TO_TOP)/rules.mak diff --git a/reactos/lib/ole32/memlockbytes.c b/reactos/lib/ole32/memlockbytes.c new file mode 100644 index 00000000000..f8770808113 --- /dev/null +++ b/reactos/lib/ole32/memlockbytes.c @@ -0,0 +1,581 @@ +/****************************************************************************** + * + * Global memory implementation of ILockBytes. + * + * Copyright 1999 Thuy Nguyen + * + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +/****************************************************************************** + * HGLOBALLockBytesImpl definition. + * + * This class imlements the ILockBytes inteface and represents a byte array + * object supported by an HGLOBAL pointer. + */ +struct HGLOBALLockBytesImpl +{ + /* + * Needs to be the first item in the stuct + * since we want to cast this in an ILockBytes pointer + */ + ICOM_VFIELD(ILockBytes); + + /* + * Reference count + */ + ULONG ref; + + /* + * Support for the LockBytes object + */ + HGLOBAL supportHandle; + + /* + * This flag is TRUE if the HGLOBAL is destroyed when the object + * is finally released. + */ + BOOL deleteOnRelease; + + /* + * Helper variable that contains the size of the byte array + */ + ULARGE_INTEGER byteArraySize; +}; + +typedef struct HGLOBALLockBytesImpl HGLOBALLockBytesImpl; + +/* + * Method definition for the HGLOBALLockBytesImpl class. + */ +HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct( + HGLOBAL hGlobal, + BOOL fDeleteOnRelease); + +void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This); + +HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface( + ILockBytes* iface, + REFIID riid, /* [in] */ + void** ppvObject); /* [iid_is][out] */ + +ULONG WINAPI HGLOBALLockBytesImpl_AddRef( + ILockBytes* iface); + +ULONG WINAPI HGLOBALLockBytesImpl_Release( + ILockBytes* iface); + +HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt( + ILockBytes* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + void* pv, /* [length_is][size_is][out] */ + ULONG cb, /* [in] */ + ULONG* pcbRead); /* [out] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt( + ILockBytes* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + const void* pv, /* [size_is][in] */ + ULONG cb, /* [in] */ + ULONG* pcbWritten); /* [out] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_Flush( + ILockBytes* iface); + +HRESULT WINAPI HGLOBALLockBytesImpl_SetSize( + ILockBytes* iface, + ULARGE_INTEGER libNewSize); /* [in] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion( + ILockBytes* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType); /* [in] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion( + ILockBytes* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType); /* [in] */ + +HRESULT WINAPI HGLOBALLockBytesImpl_Stat( + ILockBytes* iface, + STATSTG* pstatstg, /* [out] */ + DWORD grfStatFlag); /* [in] */ + +/* + * Virtual function table for the HGLOBALLockBytesImpl class. + */ +static ICOM_VTABLE(ILockBytes) HGLOBALLockBytesImpl_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + HGLOBALLockBytesImpl_QueryInterface, + HGLOBALLockBytesImpl_AddRef, + HGLOBALLockBytesImpl_Release, + HGLOBALLockBytesImpl_ReadAt, + HGLOBALLockBytesImpl_WriteAt, + HGLOBALLockBytesImpl_Flush, + HGLOBALLockBytesImpl_SetSize, + HGLOBALLockBytesImpl_LockRegion, + HGLOBALLockBytesImpl_UnlockRegion, + HGLOBALLockBytesImpl_Stat, +}; + +/****************************************************************************** + * CreateILockBytesOnHGlobal [OLE32.57] + */ +HRESULT WINAPI CreateILockBytesOnHGlobal(HGLOBAL hGlobal, + BOOL fDeleteOnRelease, + LPLOCKBYTES* ppLkbyt) +{ + HGLOBALLockBytesImpl* newLockBytes; + + newLockBytes = HGLOBALLockBytesImpl_Construct(hGlobal, fDeleteOnRelease); + + if (newLockBytes != NULL) + { + return IUnknown_QueryInterface((IUnknown*)newLockBytes, + &IID_ILockBytes, + (void**)ppLkbyt); + } + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * GetHGlobalFromILockBytes [OLE32.70] + */ +HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal) +{ + HGLOBALLockBytesImpl* const pMemLockBytes = (HGLOBALLockBytesImpl*)plkbyt; + + if (ICOM_VTBL(pMemLockBytes) == &HGLOBALLockBytesImpl_Vtbl) + *phglobal = pMemLockBytes->supportHandle; + else + *phglobal = 0; + + if (*phglobal == 0) + return E_INVALIDARG; + + return S_OK; +} + +/****************************************************************************** + * + * HGLOBALLockBytesImpl implementation + * + */ + +/****************************************************************************** + * This is the constructor for the HGLOBALLockBytesImpl class. + * + * Params: + * hGlobal - Handle that will support the stream. can be NULL. + * fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released + * when the IStream object is destroyed. + */ +HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal, + BOOL fDeleteOnRelease) +{ + HGLOBALLockBytesImpl* newLockBytes; + newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl)); + + if (newLockBytes!=0) + { + /* + * Set up the virtual function table and reference count. + */ + ICOM_VTBL(newLockBytes) = &HGLOBALLockBytesImpl_Vtbl; + newLockBytes->ref = 0; + + /* + * Initialize the support. + */ + newLockBytes->supportHandle = hGlobal; + newLockBytes->deleteOnRelease = fDeleteOnRelease; + + /* + * This method will allocate a handle if one is not supplied. + */ + if (newLockBytes->supportHandle == 0) + { + newLockBytes->supportHandle = GlobalAlloc(GMEM_MOVEABLE | + GMEM_NODISCARD, + 0); + } + + /* + * Initialize the size of the array to the size of the handle. + */ + newLockBytes->byteArraySize.u.HighPart = 0; + newLockBytes->byteArraySize.u.LowPart = GlobalSize( + newLockBytes->supportHandle); + } + + return newLockBytes; +} + +/****************************************************************************** + * This is the destructor of the HGLOBALStreamImpl class. + * + * This method will clean-up all the resources used-up by the given + * HGLOBALLockBytesImpl class. The pointer passed-in to this function will be + * freed and will not be valid anymore. + */ +void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This) +{ + /* + * Release the HGlobal if the constructor asked for that. + */ + if (This->deleteOnRelease) + { + GlobalFree(This->supportHandle); + This->supportHandle = 0; + } + + /* + * Finally, free the memory used-up by the class. + */ + HeapFree(GetProcessHeap(), 0, This); +} + +/****************************************************************************** + * This implements the IUnknown method QueryInterface for this + * class + */ +HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface( + ILockBytes* iface, + REFIID riid, /* [in] */ + void** ppvObject) /* [iid_is][out] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + /* + * Perform a sanity check on the parameters. + */ + if (ppvObject==0) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = (ILockBytes*)This; + } + else if (memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes)) == 0) + { + *ppvObject = (ILockBytes*)This; + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* + * Query Interface always increases the reference count by one when it is + * successful + */ + HGLOBALLockBytesImpl_AddRef(iface); + + return S_OK;; +} + +/****************************************************************************** + * This implements the IUnknown method AddRef for this + * class + */ +ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface) +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + This->ref++; + + return This->ref; +} + +/****************************************************************************** + * This implements the IUnknown method Release for this + * class + */ +ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface) +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + ULONG newRef; + + This->ref--; + + newRef = This->ref; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (newRef==0) + { + HGLOBALLockBytesImpl_Destroy(This); + } + + return newRef; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It reads a block of information from the byte array at the specified + * offset. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt( + ILockBytes* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + void* pv, /* [length_is][size_is][out] */ + ULONG cb, /* [in] */ + ULONG* pcbRead) /* [out] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + void* supportBuffer; + ULONG bytesReadBuffer = 0; + ULONG bytesToReadFromBuffer; + + /* + * If the caller is not interested in the number of bytes read, + * we use another buffer to avoid "if" statements in the code. + */ + if (pcbRead == 0) + pcbRead = &bytesReadBuffer; + + /* + * Make sure the offset is valid. + */ + if (ulOffset.u.LowPart > This->byteArraySize.u.LowPart) + return E_FAIL; + + /* + * Using the known size of the array, calculate the number of bytes + * to read. + */ + bytesToReadFromBuffer = min(This->byteArraySize.u.LowPart - + ulOffset.u.LowPart, cb); + + /* + * Lock the buffer in position and copy the data. + */ + supportBuffer = GlobalLock(This->supportHandle); + + memcpy(pv, + (char *) supportBuffer + ulOffset.u.LowPart, + bytesToReadFromBuffer); + + /* + * Return the number of bytes read. + */ + *pcbRead = bytesToReadFromBuffer; + + /* + * Cleanup + */ + GlobalUnlock(This->supportHandle); + + /* + * The function returns S_OK if the specified number of bytes were read + * or the end of the array was reached. + * It returns STG_E_READFAULT if the number of bytes to read does not equal + * the number of bytes actually read. + */ + if(*pcbRead == cb) + return S_OK; + + return STG_E_READFAULT; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It writes the specified bytes at the specified offset. + * position. If the array is too small, it will be resized. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt( + ILockBytes* iface, + ULARGE_INTEGER ulOffset, /* [in] */ + const void* pv, /* [size_is][in] */ + ULONG cb, /* [in] */ + ULONG* pcbWritten) /* [out] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + void* supportBuffer; + ULARGE_INTEGER newSize; + ULONG bytesWritten = 0; + + /* + * If the caller is not interested in the number of bytes written, + * we use another buffer to avoid "if" statements in the code. + */ + if (pcbWritten == 0) + pcbWritten = &bytesWritten; + + if (cb == 0) + { + return S_OK; + } + else + { + newSize.u.HighPart = 0; + newSize.u.LowPart = ulOffset.u.LowPart + cb; + } + + /* + * Verify if we need to grow the stream + */ + if (newSize.u.LowPart > This->byteArraySize.u.LowPart) + { + /* grow stream */ + if (HGLOBALLockBytesImpl_SetSize(iface, newSize) == STG_E_MEDIUMFULL) + return STG_E_MEDIUMFULL; + } + + /* + * Lock the buffer in position and copy the data. + */ + supportBuffer = GlobalLock(This->supportHandle); + + memcpy((char *) supportBuffer + ulOffset.u.LowPart, pv, cb); + + /* + * Return the number of bytes written. + */ + *pcbWritten = cb; + + /* + * Cleanup + */ + GlobalUnlock(This->supportHandle); + + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface) +{ + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It will change the size of the byte array. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_SetSize( + ILockBytes* iface, + ULARGE_INTEGER libNewSize) /* [in] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + /* + * As documented. + */ + if (libNewSize.u.HighPart != 0) + return STG_E_INVALIDFUNCTION; + + if (This->byteArraySize.u.LowPart == libNewSize.u.LowPart) + return S_OK; + + /* + * Re allocate the HGlobal to fit the new size of the stream. + */ + This->supportHandle = GlobalReAlloc(This->supportHandle, + libNewSize.u.LowPart, + 0); + + if (This->supportHandle == 0) + return STG_E_MEDIUMFULL; + + This->byteArraySize.u.LowPart = libNewSize.u.LowPart; + + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * The global memory implementation of ILockBytes does not support locking. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion( + ILockBytes* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType) /* [in] */ +{ + return STG_E_INVALIDFUNCTION; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * The global memory implementation of ILockBytes does not support locking. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion( + ILockBytes* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType) /* [in] */ +{ + return STG_E_INVALIDFUNCTION; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * This method returns information about the current + * byte array object. + * + * See the documentation of ILockBytes for more info. + */ +HRESULT WINAPI HGLOBALLockBytesImpl_Stat( + ILockBytes* iface, + STATSTG* pstatstg, /* [out] */ + DWORD grfStatFlag) /* [in] */ +{ + HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface; + + memset(pstatstg, 0, sizeof(STATSTG)); + + pstatstg->pwcsName = NULL; + pstatstg->type = STGTY_LOCKBYTES; + pstatstg->cbSize = This->byteArraySize; + + return S_OK; +} + diff --git a/reactos/lib/ole32/moniker.c b/reactos/lib/ole32/moniker.c index 332e9f9a489..0b77f1022ee 100644 --- a/reactos/lib/ole32/moniker.c +++ b/reactos/lib/ole32/moniker.c @@ -1,209 +1,508 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib\ole32\Moniker.c - * PURPOSE: Moniker implementation - * PROGRAMMER: jurgen van gael [jurgen.vangael@student.kuleuven.ac.be] - * UPDATE HISTORY: - * Created 10/05/2001 + * Monikers + * + * Copyright 1998 Marcus Meissner + * Copyright 1999 Noomen Hamza */ -/******************************************************************** + +#include + +#include +#include +#include +#include +#include + +#include -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. +#define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */ -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. +/* define the structure of the running object table elements */ +typedef struct RunObject{ -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. + IUnknown* pObj; /* points on a running object*/ + IMoniker* pmkObj; /* points on a moniker who identifies this object */ + FILETIME lastModifObj; + DWORD identRegObj; /* registration key relative to this object */ + DWORD regTypeObj; /* registration type : strong or weak */ +}RunObject; +/* define the RunningObjectTableImpl structure */ +typedef struct RunningObjectTableImpl{ -********************************************************************/ -#include "Ole32.h" + ICOM_VFIELD(IRunningObjectTable); + ULONG ref; -/* -// -// -// -WINOLEAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID iidResult, LPVOID* ppvResult) + RunObject* runObjTab; /* pointer to the first object in the table */ + DWORD runObjTabSize; /* current table size */ + DWORD runObjTabLastIndx; /* first free index element in the table. */ + DWORD runObjTabRegister; /* registration key of the next registered object */ + +} RunningObjectTableImpl; + +RunningObjectTableImpl* runningObjectTableInstance=0; + +/* IRunningObjectTable prototype functions : */ +/* IUnknown functions*/ +static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject); +static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface); +static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface); +/* IRunningObjectTable functions */ +static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister); +static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister); +static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName); +static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject); +static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime); +static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime); +static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker); +/* Local functions*/ +HRESULT WINAPI RunningObjectTableImpl_Initialize(); +HRESULT WINAPI RunningObjectTableImpl_UnInitialize(); +HRESULT WINAPI RunningObjectTableImpl_Destroy(); +HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx); + +/* Virtual function table for the IRunningObjectTable class. */ +static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl = { - return S_OK; + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + RunningObjectTableImpl_QueryInterface, + RunningObjectTableImpl_AddRef, + RunningObjectTableImpl_Release, + RunningObjectTableImpl_Register, + RunningObjectTableImpl_Revoke, + RunningObjectTableImpl_IsRunning, + RunningObjectTableImpl_GetObject, + RunningObjectTableImpl_NoteChangeTime, + RunningObjectTableImpl_GetTimeOfLastChange, + RunningObjectTableImpl_EnumRunning +}; + +/*********************************************************************** + * RunningObjectTable_QueryInterface + */ +HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject) +{ + ICOM_THIS(RunningObjectTableImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,riid,ppvObject)); + + /* validate arguments */ + if (This==0) + return CO_E_NOTINITIALIZED; + + if (ppvObject==0) + return E_INVALIDARG; + + *ppvObject = 0; + + if (IsEqualIID(&IID_IUnknown, riid)) + *ppvObject = (IRunningObjectTable*)This; + else + if (IsEqualIID(&IID_IRunningObjectTable, riid)) + *ppvObject = (IRunningObjectTable*)This; + + if ((*ppvObject)==0) + return E_NOINTERFACE; + + RunningObjectTableImpl_AddRef(iface); + + return S_OK; } - -WINOLEAPI CoInstall( - IN IBindCtx * pbc, - IN DWORD dwFlags, - IN uCLSSPEC * pClassSpec, - IN QUERYCONTEXT * pQuery, - IN LPWSTR pszCodeBase) +/*********************************************************************** + * RunningObjectTable_AddRef + */ +ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface) { - return S_OK; + ICOM_THIS(RunningObjectTableImpl,iface); + + Print(MAX_TRACE, ("(%p)\n",This)); + + return ++(This->ref); } - -WINOLEAPI MkParseDisplayName(IN LPBC pbc, IN LPCOLESTR szUserName, - OUT ULONG FAR * pchEaten, OUT LPMONIKER FAR * ppmk) +/*********************************************************************** + * RunningObjectTable_Initialize + */ +HRESULT WINAPI RunningObjectTableImpl_Destroy() { - return S_OK; + Print(MAX_TRACE, ("()\n")); + + if (runningObjectTableInstance==NULL) + return E_INVALIDARG; + + /* free the ROT table memory */ + HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab); + + /* free the ROT structure memory */ + HeapFree(GetProcessHeap(),0,runningObjectTableInstance); + + return S_OK; } -WINOLEAPI MonikerRelativePathTo(IN LPMONIKER pmkSrc, IN LPMONIKER pmkDest, OUT LPMONIKER - FAR* ppmkRelPath, IN BOOL dwReserved) +/*********************************************************************** + * RunningObjectTable_Release + */ +ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface) { - return S_OK; -} + DWORD i; + ICOM_THIS(RunningObjectTableImpl,iface); -WINOLEAPI MonikerCommonPrefixWith(IN LPMONIKER pmkThis, IN LPMONIKER pmkOther, - OUT LPMONIKER FAR* ppmkCommon) -{ - return S_OK; -} + Print(MAX_TRACE, ("(%p)\n",This)); -WINOLEAPI CreateBindCtx(IN DWORD reserved, OUT LPBC FAR* ppbc) -{ - return S_OK; -} + This->ref--; -WINOLEAPI CreateGenericComposite(IN LPMONIKER pmkFirst, IN LPMONIKER pmkRest, - OUT LPMONIKER FAR* ppmkComposite) -{ - return S_OK; -} + /* unitialize ROT structure if there's no more reference to it*/ + if (This->ref==0){ -WINOLEAPI GetClassFile (IN LPCOLESTR szFilename, OUT CLSID FAR* pclsid) -{ - // wine stuff - - /*IStorage *pstg=0; - HRESULT res; - int nbElm=0,length=0,i=0; - LONG sizeProgId=20; - LPOLESTR *pathDec=0,absFile=0,progId=0; - WCHAR extention[100]={0}; - - TRACE("()\n"); - - /* if the file contain a storage object the return the CLSID writen by IStorage_SetClass method - if((StgIsStorageFile(filePathName))==S_OK){ - - res=StgOpenStorage(filePathName,NULL,STGM_READ | STGM_SHARE_DENY_WRITE,NULL,0,&pstg); - - if (SUCCEEDED(res)) - res=ReadClassStg(pstg,pclsid); - - IStorage_Release(pstg); - - return res; - } - /* if the file is not a storage object then attemps to match various bits in the file against a - pattern in the registry. this case is not frequently used ! so I present only the psodocode for - this case - - for(i=0;irunObjTabLastIndx;i++) + { + if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0) + IUnknown_Release(This->runObjTab[i].pObj); + + IMoniker_Release(This->runObjTab[i].pmkObj); } - */ + /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only + * when RunningObjectTableImpl_UnInitialize function is called + */ - /* if the obove strategies fail then search for the extension key in the registry + /* there's no more elements in the table */ + This->runObjTabRegister=0; + This->runObjTabLastIndx=0; - /* get the last element (absolute file) in the path name - nbElm=FileMonikerImpl_DecomposePath(filePathName,&pathDec); - absFile=pathDec[nbElm-1]; - - /* failed if the path represente a directory and not an absolute file name - if (lstrcmpW(absFile,(LPOLESTR)"\\")) - return MK_E_INVALIDEXTENSION; - - /* get the extension of the file - length=lstrlenW(absFile); - for(i=length-1; ( (i>=0) && (extention[i]=absFile[i]) );i--); - - /* get the progId associated to the extension - progId=CoTaskMemAlloc(sizeProgId); - - res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId); - - if (res==ERROR_MORE_DATA){ - - progId = CoTaskMemRealloc(progId,sizeProgId); - res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId); + return 0; } - if (res==ERROR_SUCCESS) - /* return the clsid associated to the progId - res= CLSIDFromProgID(progId,pclsid); - for(i=0; pathDec[i]!=NULL;i++) - CoTaskMemFree(pathDec[i]); - CoTaskMemFree(pathDec); + return This->ref; +} - CoTaskMemFree(progId); +/*********************************************************************** + * RunningObjectTable_Initialize + */ +HRESULT WINAPI RunningObjectTableImpl_Initialize() +{ + Print(MAX_TRACE, ("()\n")); - if (res==ERROR_SUCCESS) - return res; + /* create the unique instance of the RunningObjectTableImpl structure */ + runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl)); - return MK_E_INVALIDEXTENSION; + if (runningObjectTableInstance == 0) + return E_OUTOFMEMORY; + + /* initialize the virtual table function */ + ICOM_VTBL(runningObjectTableInstance) = &VT_RunningObjectTableImpl; + + /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */ + /* the ROT refered many times not in the same time (all the objects in the ROT will */ + /* be removed every time the ROT is removed ) */ + runningObjectTableInstance->ref = 1; + + /* allocate space memory for the table which contains all the running objects */ + runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE])); + + if (runningObjectTableInstance->runObjTab == NULL) + return E_OUTOFMEMORY; + + runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE; + runningObjectTableInstance->runObjTabRegister=1; + runningObjectTableInstance->runObjTabLastIndx=0; + + return S_OK; +} + +/*********************************************************************** + * RunningObjectTable_UnInitialize + */ +HRESULT WINAPI RunningObjectTableImpl_UnInitialize() +{ + Print(MAX_TRACE, ("()\n")); + + if (runningObjectTableInstance==NULL) + return E_POINTER; + + RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance); + + RunningObjectTableImpl_Destroy(); + + return S_OK; +} + +/*********************************************************************** + * RunningObjectTable_Register + */ +HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, + DWORD grfFlags, /* Registration options */ + IUnknown *punkObject, /* Pointer to the object being registered */ + IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */ + DWORD *pdwRegister) /* Pointer to the value identifying the registration */ +{ + HRESULT res=S_OK; + ICOM_THIS(RunningObjectTableImpl,iface); + + Print(MAX_TRACE, ("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister)); + + /* there's only two types of register : strong and or weak registration (only one must be passed on parameter) */ + if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) && + (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) && + (grfFlags) ) + return E_INVALIDARG; + + if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL) + return E_INVALIDARG; + + /* verify if the object to be registered was registered before */ + if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK) + res = MK_S_MONIKERALREADYREGISTERED; + + /* put the new registered object in the first free element in the table */ + This->runObjTab[This->runObjTabLastIndx].pObj = punkObject; + This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName; + This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags; + This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister; + CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj)); + + /* gives a registration identifier to the registered object*/ + (*pdwRegister)= This->runObjTabRegister; + + if (This->runObjTabRegister == 0xFFFFFFFF){ + + Print(MIN_TRACE, ("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister)); return E_FAIL; } + This->runObjTabRegister++; + This->runObjTabLastIndx++; + + if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */ + This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */ + This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab, + This->runObjTabSize * sizeof(RunObject)); + if (!This->runObjTab) + return E_OUTOFMEMORY; + } + /* add a reference to the object in the strong registration case */ + if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 ) + IUnknown_AddRef(punkObject); -WINOLEAPI CreateClassMoniker(IN REFCLSID rclsid, OUT LPMONIKER FAR* ppmk) -{ - return S_OK; + IMoniker_AddRef(pmkObjectName); + + return res; } - -WINOLEAPI CreateFileMoniker(IN LPCOLESTR lpszPathName, OUT LPMONIKER FAR* ppmk) +/*********************************************************************** + * RunningObjectTable_Revoke + */ +HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface, + DWORD dwRegister) /* Value identifying registration to be revoked*/ { - return S_OK; + + DWORD index,j; + ICOM_THIS(RunningObjectTableImpl,iface); + + Print(MAX_TRACE, ("(%p,%ld)\n",This,dwRegister)); + + /* verify if the object to be revoked was registered before or not */ + if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE) + + return E_INVALIDARG; + + /* release the object if it was registered with a strong registrantion option */ + if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0) + IUnknown_Release(This->runObjTab[index].pObj); + + IMoniker_Release(This->runObjTab[index].pmkObj); + + /* remove the object from the table */ + for(j=index; jrunObjTabLastIndx-1; j++) + This->runObjTab[j]= This->runObjTab[j+1]; + + This->runObjTabLastIndx--; + + return S_OK; } +/*********************************************************************** + * RunningObjectTable_IsRunning + */ +HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface, + IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */ +{ + ICOM_THIS(RunningObjectTableImpl,iface); -WINOLEAPI CreateItemMoniker(IN LPCOLESTR lpszDelim, IN LPCOLESTR lpszItem, - OUT LPMONIKER FAR* ppmk) -{ - return S_OK; + Print(MAX_TRACE, ("(%p,%p)\n",This,pmkObjectName)); + + return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL); } -WINOLEAPI CreateAntiMoniker(OUT LPMONIKER FAR* ppmk) +/*********************************************************************** + * RunningObjectTable_GetObject + */ +HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface, + IMoniker *pmkObjectName,/* Pointer to the moniker on the object */ + IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */ { - return S_OK; + DWORD index; + ICOM_THIS(RunningObjectTableImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject)); + + if (ppunkObject==NULL) + return E_POINTER; + + *ppunkObject=0; + + /* verify if the object was registered before or not */ + if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE) + return MK_E_UNAVAILABLE; + + /* add a reference to the object then set output object argument */ + IUnknown_AddRef(This->runObjTab[index].pObj); + *ppunkObject=This->runObjTab[index].pObj; + + return S_OK; } -WINOLEAPI CreatePointerMoniker(IN LPUNKNOWN punk, OUT LPMONIKER FAR* ppmk) +/*********************************************************************** + * RunningObjectTable_NoteChangeTime + */ +HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, + DWORD dwRegister, /* Value identifying registration being updated */ + FILETIME *pfiletime) /* Pointer to structure containing object's last change time */ { - return S_OK; + DWORD index=-1; + ICOM_THIS(RunningObjectTableImpl,iface); + + Print(MAX_TRACE, ("(%p,%ld,%p)\n",This,dwRegister,pfiletime)); + + /* verify if the object to be changed was registered before or not */ + if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE) + return E_INVALIDARG; + + /* set the new value of the last time change */ + This->runObjTab[index].lastModifObj= (*pfiletime); + + return S_OK; +} + +/*********************************************************************** + * RunningObjectTable_GetTimeOfLastChange + */ +HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, + IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */ + FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */ +{ + DWORD index=-1; + ICOM_THIS(RunningObjectTableImpl,iface); + + Print(MAX_TRACE, ("(%p,%p,%p)\n",This,pmkObjectName,pfiletime)); + + if (pmkObjectName==NULL || pfiletime==NULL) + return E_INVALIDARG; + + /* verify if the object was registered before or not */ + if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE) + return MK_E_UNAVAILABLE;; + + (*pfiletime)= This->runObjTab[index].lastModifObj; + + return S_OK; } -WINOLEAPI CreateObjrefMoniker(IN LPUNKNOWN punk, OUT LPMONIKER FAR * ppmk) +/*********************************************************************** + * RunningObjectTable_EnumRunning + */ +HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, + IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */ { - return S_OK; + UNIMPLEMENTED; + return E_NOTIMPL; } - -WINOLEAPI GetRunningObjectTable( IN DWORD reserved, OUT LPRUNNINGOBJECTTABLE FAR* pprot) +/*********************************************************************** + * GetObjectIndex + */ +HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This, + DWORD identReg, + IMoniker* pmk, + DWORD *indx) { - return S_OK; -}*/ + + DWORD i; + + Print(MAX_TRACE, ("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx)); + + if (pmk!=NULL) + /* search object identified by a moniker */ + for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++); + else + /* search object identified by a register identifier */ + for(i=0;((irunObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++); + + if (i==This->runObjTabLastIndx) return S_FALSE; + + if (indx != NULL) *indx=i; + + return S_OK; +} + +/****************************************************************************** + * GetRunningObjectTable16 [OLE2.30] + */ +HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/*********************************************************************** + * GetRunningObjectTable (OLE2.73) + */ +HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot) +{ + IID riid=IID_IRunningObjectTable; + HRESULT res; + + Print(MAX_TRACE, ("()\n")); + + if (reserved!=0) + return E_UNEXPECTED; + + if(runningObjectTableInstance==NULL) + return CO_E_NOTINITIALIZED; + + res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot); + + return res; +} + +/****************************************************************************** + * OleRun [OLE32.123] + */ +HRESULT WINAPI OleRun(LPUNKNOWN pUnknown) +{ + IRunnableObject *runable; + ICOM_THIS(IRunnableObject,pUnknown); + LRESULT ret; + + ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable); + if (ret) + return 0; /* Appears to return no error. */ + ret = IRunnableObject_Run(runable,NULL); + IRunnableObject_Release(runable); + return ret; +} + +/****************************************************************************** + * MkParseDisplayName [OLE32.81] + */ +HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName, + LPDWORD pchEaten, LPMONIKER *ppmk) +{ + Print(MIN_TRACE, ("(%p, %S, %p, %p): stub.\n", pbc, szUserName, pchEaten, *ppmk)); + if (!(IsValidInterface((LPUNKNOWN) pbc))) + return E_INVALIDARG; + + return MK_E_SYNTAX; +} diff --git a/reactos/lib/ole32/ole2.c b/reactos/lib/ole32/ole2.c index 934803ffde9..29e941b803b 100644 --- a/reactos/lib/ole32/ole2.c +++ b/reactos/lib/ole32/ole2.c @@ -1,254 +1,2228 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib\ole32\Ole2.c - * PURPOSE: Object Linking And Embedding implementation - * PROGRAMMER: jurgen van gael [jurgen.vangael@student.kuleuven.ac.be] - * UPDATE HISTORY: - * Created 12/05/2001 + * OLE2 library + * + * Copyright 1995 Martin von Loewis + * Copyright 1999 Francis Beaudet + * Copyright 1999 Noel Borthwick */ -/******************************************************************** +#include +#include +#include -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. +#include +#include +#include +#include +#include "ole32_main.h" -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. - - -********************************************************************/ -#include "Ole32.h" +#include #if 0 -WINOLEAPI_(DWORD) OleBuildVersion( VOID ){return S_OK;} -#endif -WINOLEAPI -OleInitialize (IN LPVOID pvReserved) +/****************************************************************************** + * These are static/global variables and internal data structures that the + * OLE module uses to maintain it's state. + */ +typedef struct tagDropTargetNode { + HWND hwndTarget; + IDropTarget* dropTarget; + struct tagDropTargetNode* prevDropTarget; + struct tagDropTargetNode* nextDropTarget; +} DropTargetNode; + +typedef struct tagTrackerWindowInfo +{ + IDataObject* dataObject; + IDropSource* dropSource; + DWORD dwOKEffect; + DWORD* pdwEffect; + BOOL trackingDone; + HRESULT returnValue; + + BOOL escPressed; + HWND curDragTargetHWND; + IDropTarget* curDragTarget; +} TrackerWindowInfo; + +typedef struct tagOleMenuDescriptor /* OleMenuDescriptor */ +{ + HWND hwndFrame; /* The containers frame window */ + HWND hwndActiveObject; /* The active objects window */ + OLEMENUGROUPWIDTHS mgw; /* OLE menu group widths for the shared menu */ + HMENU hmenuCombined; /* The combined menu */ + BOOL bIsServerItem; /* True if the currently open popup belongs to the server */ +} OleMenuDescriptor; + +typedef struct tagOleMenuHookItem /* OleMenu hook item in per thread hook list */ +{ + DWORD tid; /* Thread Id */ + HANDLE hHeap; /* Heap this is allocated from */ + HHOOK GetMsg_hHook; /* message hook for WH_GETMESSAGE */ + HHOOK CallWndProc_hHook; /* message hook for WH_CALLWNDPROC */ + struct tagOleMenuHookItem *next; +} OleMenuHookItem; + +static OleMenuHookItem *hook_list; + +/* + * This is the lock count on the OLE library. It is controlled by the + * OLEInitialize/OLEUninitialize methods. + */ +static ULONG OLE_moduleLockCount = 0; + +/* + * Name of our registered window class. + */ +static const char OLEDD_DRAGTRACKERCLASS[] = "WineDragDropTracker32"; + +/* + * This is the head of the Drop target container. + */ +static DropTargetNode* targetListHead = NULL; + +/****************************************************************************** + * These are the prototypes of miscelaneous utility methods + */ +static void OLEUTL_ReadRegistryDWORDValue(HKEY regKey, DWORD* pdwValue); + +/****************************************************************************** + * These are the prototypes of the utility methods used to manage a shared menu + */ +static void OLEMenu_Initialize(); +static void OLEMenu_UnInitialize(); +BOOL OLEMenu_InstallHooks( DWORD tid ); +BOOL OLEMenu_UnInstallHooks( DWORD tid ); +OleMenuHookItem * OLEMenu_IsHookInstalled( DWORD tid ); +static BOOL OLEMenu_FindMainMenuIndex( HMENU hMainMenu, HMENU hPopupMenu, UINT *pnPos ); +BOOL OLEMenu_SetIsServerMenu( HMENU hmenu, OleMenuDescriptor *pOleMenuDescriptor ); +LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK OLEMenu_GetMsgProc(INT code, WPARAM wParam, LPARAM lParam); + +/****************************************************************************** + * These are the prototypes of the OLE Clipboard initialization methods (in clipboard.c) + */ +void OLEClipbrd_UnInitialize(); +void OLEClipbrd_Initialize(); + +/****************************************************************************** + * These are the prototypes of the utility methods used for OLE Drag n Drop + */ +static void OLEDD_Initialize(); +static void OLEDD_UnInitialize(); +static void OLEDD_InsertDropTarget( + DropTargetNode* nodeToAdd); +static DropTargetNode* OLEDD_ExtractDropTarget( + HWND hwndOfTarget); +static DropTargetNode* OLEDD_FindDropTarget( + HWND hwndOfTarget); +static LRESULT WINAPI OLEDD_DragTrackerWindowProc( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +static void OLEDD_TrackMouseMove( + TrackerWindowInfo* trackerInfo, + POINT mousePos, + DWORD keyState); +static void OLEDD_TrackStateChange( + TrackerWindowInfo* trackerInfo, + POINT mousePos, + DWORD keyState); +static DWORD OLEDD_GetButtonState(); + + +/****************************************************************************** + * OleBuildVersion [OLE2.1] + */ +DWORD WINAPI OleBuildVersion(void) +{ + Print(MAX_TRACE, ("Returning version %d, build %d.\n", 1, 0)); + return (1<<16)+0; +} + +/*********************************************************************** + * OleInitialize (OLE2.2) (OLE32.108) + */ +HRESULT WINAPI OleInitialize(LPVOID reserved) +{ + HRESULT hr; + + Print(MAX_TRACE, ("(%p)\n", reserved)); + + /* + * The first duty of the OleInitialize is to initialize the COM libraries. + */ + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + /* + * If the CoInitializeEx call failed, the OLE libraries can't be + * initialized. + */ + if (FAILED(hr)) + return hr; + + /* + * Then, it has to initialize the OLE specific modules. + * This includes: + * Clipboard + * Drag and Drop + * Object linking and Embedding + * In-place activation + */ + if (OLE_moduleLockCount==0) +{ + /* + * Initialize the libraries. + */ + Print(MAX_TRACE, ("() - Initializing the OLE libraries\n")); + + /* + * OLE Clipboard + */ + OLEClipbrd_Initialize(); + + /* + * Drag and Drop + */ + OLEDD_Initialize(); + + /* + * OLE shared menu + */ + OLEMenu_Initialize(); +} + + /* + * Then, we increase the lock count on the OLE module. + */ + OLE_moduleLockCount++; + + return hr; +} + +/****************************************************************************** + * CoGetCurrentProcess [COMPOBJ.34] [OLE2.2][OLE32.108] + * + * NOTES + * Is DWORD really the correct return type for this function? + */ +DWORD WINAPI CoGetCurrentProcess(void) +{ + return GetCurrentProcessId(); +} + +/****************************************************************************** + * OleUninitialize [OLE2.3] [OLE32.131] + */ +void WINAPI OleUninitialize(void) +{ + Print(MAX_TRACE, ("()\n")); + + /* + * Decrease the lock count on the OLE module. + */ + OLE_moduleLockCount--; + + /* + * If we hit the bottom of the lock stack, free the libraries. + */ + if (OLE_moduleLockCount==0) + { + /* + * Actually free the libraries. + */ + Print(MAX_TRACE, ("() - Freeing the last reference count\n")); + + /* + * OLE Clipboard + */ + OLEClipbrd_UnInitialize(); + + /* + * Drag and Drop + */ + OLEDD_UnInitialize(); + + /* + * OLE shared menu + */ + OLEMenu_UnInitialize(); + } + + /* + * Then, uninitialize the COM libraries. + */ + CoUninitialize(); +} + +/****************************************************************************** + * CoRegisterMessageFilter [OLE32.38] + */ +HRESULT WINAPI CoRegisterMessageFilter( + LPMESSAGEFILTER lpMessageFilter, /* [in] Pointer to interface */ + LPMESSAGEFILTER *lplpMessageFilter /* [out] Indirect pointer to prior instance if non-NULL */ +) { + Print(MIN_TRACE, ("stub\n")); + if (lplpMessageFilter) { + *lplpMessageFilter = NULL; + } + return S_OK; +} + +/****************************************************************************** + * OleInitializeWOW [OLE32.109] + */ +HRESULT WINAPI OleInitializeWOW(DWORD x) { + Print(MIN_TRACE, ("(0x%08lx),stub!\n",x)); + return 0; +} + +/*********************************************************************** + * RegisterDragDrop16 (OLE2.35) + */ +HRESULT WINAPI RegisterDragDrop16( + DWORD hwnd, + LPDROPTARGET pDropTarget +) { + UNIMPLEMENTED; + return S_OK; +} + +/*********************************************************************** + * RegisterDragDrop (OLE32.139) + */ +HRESULT WINAPI RegisterDragDrop( + HWND hwnd, + LPDROPTARGET pDropTarget) +{ + DropTargetNode* dropTargetInfo; + + Print(MAX_TRACE, ("(0x%x,%p)\n", hwnd, pDropTarget)); + + /* + * First, check if the window is already registered. + */ + dropTargetInfo = OLEDD_FindDropTarget(hwnd); + + if (dropTargetInfo!=NULL) + return DRAGDROP_E_ALREADYREGISTERED; + + /* + * If it's not there, we can add it. We first create a node for it. + */ + dropTargetInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(DropTargetNode)); + + if (dropTargetInfo==NULL) + return E_OUTOFMEMORY; + + dropTargetInfo->hwndTarget = hwnd; + dropTargetInfo->prevDropTarget = NULL; + dropTargetInfo->nextDropTarget = NULL; + + /* + * Don't forget that this is an interface pointer, need to nail it down since + * we keep a copy of it. + */ + dropTargetInfo->dropTarget = pDropTarget; + IDropTarget_AddRef(dropTargetInfo->dropTarget); + + OLEDD_InsertDropTarget(dropTargetInfo); + + return S_OK; +} + +/*********************************************************************** + * RevokeDragDrop16 (OLE2.36) + */ +HRESULT WINAPI RevokeDragDrop16( + DWORD hwnd +) { + UNIMPLEMENTED; + return S_OK; +} + +/*********************************************************************** + * RevokeDragDrop (OLE32.141) + */ +HRESULT WINAPI RevokeDragDrop( + HWND hwnd) +{ + DropTargetNode* dropTargetInfo; + + Print(MAX_TRACE, ("(0x%x)\n", hwnd)); + + /* + * First, check if the window is already registered. + */ + dropTargetInfo = OLEDD_ExtractDropTarget(hwnd); + + /* + * If it ain't in there, it's an error. + */ + if (dropTargetInfo==NULL) + return DRAGDROP_E_NOTREGISTERED; + + /* + * If it's in there, clean-up it's used memory and + * references + */ + IDropTarget_Release(dropTargetInfo->dropTarget); + HeapFree(GetProcessHeap(), 0, dropTargetInfo); + + return S_OK; +} + +/*********************************************************************** + * OleRegGetUserType (OLE32.122) + * + * This implementation of OleRegGetUserType ignores the dwFormOfType + * parameter and always returns the full name of the object. This is + * not too bad since this is the case for many objects because of the + * way they are registered. + */ +HRESULT WINAPI OleRegGetUserType( + REFCLSID clsid, + DWORD dwFormOfType, + LPOLESTR* pszUserType) +{ + char keyName[60]; + DWORD dwKeyType; + DWORD cbData; + HKEY clsidKey; + LONG hres; + LPBYTE buffer; + HRESULT retVal; + /* + * Initialize the out parameter. + */ + *pszUserType = NULL; + + /* + * Build the key name we're looking for + */ + sprintf( keyName, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\", + clsid->Data1, clsid->Data2, clsid->Data3, + clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], + clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); + + Print(MAX_TRACE, ("(%s, %ld, %p)\n", keyName, dwFormOfType, pszUserType)); + + /* + * Open the class id Key + */ + hres = RegOpenKeyA(HKEY_CLASSES_ROOT, + keyName, + &clsidKey); + + if (hres != ERROR_SUCCESS) + return REGDB_E_CLASSNOTREG; + + /* + * Retrieve the size of the name string. + */ + cbData = 0; + + hres = RegQueryValueExA(clsidKey, + "", + NULL, + &dwKeyType, + NULL, + &cbData); + + if (hres!=ERROR_SUCCESS) + { + RegCloseKey(clsidKey); + return REGDB_E_READREGDB; + } + + /* + * Allocate a buffer for the registry value. + */ + *pszUserType = CoTaskMemAlloc(cbData*2); + + if (*pszUserType==NULL) + { + RegCloseKey(clsidKey); + return E_OUTOFMEMORY; + } + + buffer = HeapAlloc(GetProcessHeap(), 0, cbData); + + if (buffer == NULL) + { + RegCloseKey(clsidKey); + CoTaskMemFree(*pszUserType); + *pszUserType=NULL; + return E_OUTOFMEMORY; + } + + hres = RegQueryValueExA(clsidKey, + "", + NULL, + &dwKeyType, + buffer, + &cbData); + + RegCloseKey(clsidKey); + + + if (hres!=ERROR_SUCCESS) + { + CoTaskMemFree(*pszUserType); + *pszUserType=NULL; + + retVal = REGDB_E_READREGDB; + } + else + { + MultiByteToWideChar( CP_ACP, 0, buffer, -1, *pszUserType, cbData /*FIXME*/ ); + retVal = S_OK; + } + HeapFree(GetProcessHeap(), 0, buffer); + + return retVal; +} + +/*********************************************************************** + * DoDragDrop [OLE32.65] + */ +HRESULT WINAPI DoDragDrop ( + IDataObject *pDataObject, /* [in] ptr to the data obj */ + IDropSource* pDropSource, /* [in] ptr to the source obj */ + DWORD dwOKEffect, /* [in] effects allowed by the source */ + DWORD *pdwEffect) /* [out] ptr to effects of the source */ +{ + TrackerWindowInfo trackerInfo; + HWND hwndTrackWindow; + MSG msg; + + Print(MAX_TRACE, ("(DataObject %p, DropSource %p)\n", pDataObject, pDropSource)); + + /* + * Setup the drag n drop tracking window. + */ + trackerInfo.dataObject = pDataObject; + trackerInfo.dropSource = pDropSource; + trackerInfo.dwOKEffect = dwOKEffect; + trackerInfo.pdwEffect = pdwEffect; + trackerInfo.trackingDone = FALSE; + trackerInfo.escPressed = FALSE; + trackerInfo.curDragTargetHWND = 0; + trackerInfo.curDragTarget = 0; + + hwndTrackWindow = CreateWindowA(OLEDD_DRAGTRACKERCLASS, + "TrackerWindow", + WS_POPUP, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + 0, + 0, + 0, + (LPVOID)&trackerInfo); + + if (hwndTrackWindow!=0) + { + /* + * Capture the mouse input + */ + SetCapture(hwndTrackWindow); + + /* + * Pump messages. All mouse input should go the the capture window. + */ + while (!trackerInfo.trackingDone && GetMessageA(&msg, 0, 0, 0) ) + { + if ( (msg.message >= WM_KEYFIRST) && + (msg.message <= WM_KEYLAST) ) + { + /* + * When keyboard messages are sent to windows on this thread, we + * want to ignore notify the drop source that the state changed. + * in the case of the Escape key, we also notify the drop source + * we give it a special meaning. + */ + if ( (msg.message==WM_KEYDOWN) && + (msg.wParam==VK_ESCAPE) ) + { + trackerInfo.escPressed = TRUE; + } + + /* + * Notify the drop source. + */ + OLEDD_TrackStateChange(&trackerInfo, + msg.pt, + OLEDD_GetButtonState()); + } + else + { + /* + * Dispatch the messages only when it's not a keyboard message. + */ + DispatchMessageA(&msg); + } + } + + /* + * Destroy the temporary window. + */ + DestroyWindow(hwndTrackWindow); + + return trackerInfo.returnValue; + } + return E_FAIL; } -WINOLEAPI_(void) -OleUninitialize(void) +/*********************************************************************** + * OleQueryLinkFromData [OLE32.118] + */ +HRESULT WINAPI OleQueryLinkFromData( + IDataObject* pSrcDataObject) { - return; + Print(MIN_TRACE, ("(%p),stub!\n", pSrcDataObject)); + return S_OK; } +/*********************************************************************** + * OleRegGetMiscStatus [OLE32.121] + */ +HRESULT WINAPI OleRegGetMiscStatus( + REFCLSID clsid, + DWORD dwAspect, + DWORD* pdwStatus) +{ + char keyName[60]; + HKEY clsidKey; + HKEY miscStatusKey; + HKEY aspectKey; + LONG result; + + /* + * Initialize the out parameter. + */ + *pdwStatus = 0; + + /* + * Build the key name we're looking for + */ + sprintf( keyName, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\", + clsid->Data1, clsid->Data2, clsid->Data3, + clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], + clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); + + Print(MAX_TRACE, ("(%s, %ld, %p)\n", keyName, dwAspect, pdwStatus)); + + /* + * Open the class id Key + */ + result = RegOpenKeyA(HKEY_CLASSES_ROOT, + keyName, + &clsidKey); + + if (result != ERROR_SUCCESS) + return REGDB_E_CLASSNOTREG; + + /* + * Get the MiscStatus + */ + result = RegOpenKeyA(clsidKey, + "MiscStatus", + &miscStatusKey); + + + if (result != ERROR_SUCCESS) + { + RegCloseKey(clsidKey); + return REGDB_E_READREGDB; + } + + /* + * Read the default value + */ + OLEUTL_ReadRegistryDWORDValue(miscStatusKey, pdwStatus); + + /* + * Open the key specific to the requested aspect. + */ + sprintf(keyName, "%ld", dwAspect); + + result = RegOpenKeyA(miscStatusKey, + keyName, + &aspectKey); + + if (result == ERROR_SUCCESS) + { + OLEUTL_ReadRegistryDWORDValue(aspectKey, pdwStatus); + RegCloseKey(aspectKey); + } + + /* + * Cleanup + */ + RegCloseKey(miscStatusKey); + RegCloseKey(clsidKey); + + return S_OK; +} + +/****************************************************************************** + * OleSetContainedObject [OLE32.128] + */ +HRESULT WINAPI OleSetContainedObject( + LPUNKNOWN pUnknown, + BOOL fContained) +{ + IRunnableObject* runnable = NULL; + HRESULT hres; + + Print(MAX_TRACE, ("(%p,%x), stub!\n", pUnknown, fContained)); + + hres = IUnknown_QueryInterface(pUnknown, + &IID_IRunnableObject, + (void**)&runnable); + + if (SUCCEEDED(hres)) + { + hres = IRunnableObject_SetContainedObject(runnable, fContained); + + IRunnableObject_Release(runnable); + + return hres; + } + + return S_OK; +} + +/****************************************************************************** + * OleLoad [OLE32.112] + */ +HRESULT WINAPI OleLoad( + LPSTORAGE pStg, + REFIID riid, + LPOLECLIENTSITE pClientSite, + LPVOID* ppvObj) +{ + IPersistStorage* persistStorage = NULL; + IOleObject* oleObject = NULL; + STATSTG storageInfo; + HRESULT hres; + + Print(MAX_TRACE, ("(%p,%p,%p,%p)\n", pStg, riid, pClientSite, ppvObj)); + + /* + * TODO, Conversion ... OleDoAutoConvert + */ + + /* + * Get the class ID for the object. + */ + hres = IStorage_Stat(pStg, &storageInfo, STATFLAG_NONAME); + + /* + * Now, try and create the handler for the object + */ + hres = CoCreateInstance(&storageInfo.clsid, + NULL, + CLSCTX_INPROC_HANDLER, + &IID_IOleObject, + (void**)&oleObject); + + /* + * If that fails, as it will most times, load the default + * OLE handler. + */ + if (FAILED(hres)) + { + hres = OleCreateDefaultHandler(&storageInfo.clsid, + NULL, + &IID_IOleObject, + (void**)&oleObject); + } + + /* + * If we couldn't find a handler... this is bad. Abort the whole thing. + */ + if (FAILED(hres)) + return hres; + + /* + * Inform the new object of it's client site. + */ + hres = IOleObject_SetClientSite(oleObject, pClientSite); + + /* + * Initialize the object with it's IPersistStorage interface. + */ + hres = IOleObject_QueryInterface(oleObject, + &IID_IPersistStorage, + (void**)&persistStorage); + + if (SUCCEEDED(hres)) + { + IPersistStorage_Load(persistStorage, pStg); + + IPersistStorage_Release(persistStorage); + persistStorage = NULL; + } + + /* + * Return the requested interface to the caller. + */ + hres = IOleObject_QueryInterface(oleObject, riid, ppvObj); + + /* + * Cleanup interfaces used internally + */ + IOleObject_Release(oleObject); + + return hres; +} + +/*********************************************************************** + * OleSave [OLE32.124] + */ +HRESULT WINAPI OleSave( + LPPERSISTSTORAGE pPS, + LPSTORAGE pStg, + BOOL fSameAsLoad) +{ + HRESULT hres; + CLSID objectClass; + + Print(MAX_TRACE, ("(%p,%p,%x)\n", pPS, pStg, fSameAsLoad)); + + /* + * First, we transfer the class ID (if available) + */ + hres = IPersistStorage_GetClassID(pPS, &objectClass); + + if (SUCCEEDED(hres)) + { + WriteClassStg(pStg, &objectClass); + } + + /* + * Then, we ask the object to save itself to the + * storage. If it is successful, we commit the storage. + */ + hres = IPersistStorage_Save(pPS, pStg, fSameAsLoad); + + if (SUCCEEDED(hres)) + { + IStorage_Commit(pStg, + STGC_DEFAULT); + } + + return hres; +} + + +/****************************************************************************** + * OleLockRunning [OLE32.114] + */ +HRESULT WINAPI OleLockRunning(LPUNKNOWN pUnknown, BOOL fLock, BOOL fLastUnlockCloses) +{ + IRunnableObject* runnable = NULL; + HRESULT hres; + + Print(MAX_TRACE, ("(%p,%x,%x)\n", pUnknown, fLock, fLastUnlockCloses)); + + hres = IUnknown_QueryInterface(pUnknown, + &IID_IRunnableObject, + (void**)&runnable); + + if (SUCCEEDED(hres)) + { + hres = IRunnableObject_LockRunning(runnable, fLock, fLastUnlockCloses); + + IRunnableObject_Release(runnable); + + return hres; + } + else + return E_INVALIDARG; +} + + +/************************************************************************** + * Internal methods to manage the shared OLE menu in response to the + * OLE***MenuDescriptor API + */ + +/*** + * OLEMenu_Initialize() + * + * Initializes the OLEMENU data structures. + */ +static void OLEMenu_Initialize() +{ +} + +/*** + * OLEMenu_UnInitialize() + * + * Releases the OLEMENU data structures. + */ +static void OLEMenu_UnInitialize() +{ +} + +/************************************************************************* + * OLEMenu_InstallHooks + * Install thread scope message hooks for WH_GETMESSAGE and WH_CALLWNDPROC + * + * RETURNS: TRUE if message hooks were succesfully installed + * FALSE on failure + */ +BOOL OLEMenu_InstallHooks( DWORD tid ) +{ + OleMenuHookItem *pHookItem = NULL; + + /* Create an entry for the hook table */ + if ( !(pHookItem = HeapAlloc(GetProcessHeap(), 0, + sizeof(OleMenuHookItem)) ) ) + return FALSE; + + pHookItem->tid = tid; + pHookItem->hHeap = GetProcessHeap(); + + /* Install a thread scope message hook for WH_GETMESSAGE */ + pHookItem->GetMsg_hHook = SetWindowsHookExA( WH_GETMESSAGE, OLEMenu_GetMsgProc, + 0, GetCurrentThreadId() ); + if ( !pHookItem->GetMsg_hHook ) + goto CLEANUP; + + /* Install a thread scope message hook for WH_CALLWNDPROC */ + pHookItem->CallWndProc_hHook = SetWindowsHookExA( WH_CALLWNDPROC, OLEMenu_CallWndProc, + 0, GetCurrentThreadId() ); + if ( !pHookItem->CallWndProc_hHook ) + goto CLEANUP; + + /* Insert the hook table entry */ + pHookItem->next = hook_list; + hook_list = pHookItem; + + return TRUE; + +CLEANUP: + /* Unhook any hooks */ + if ( pHookItem->GetMsg_hHook ) + UnhookWindowsHookEx( pHookItem->GetMsg_hHook ); + if ( pHookItem->CallWndProc_hHook ) + UnhookWindowsHookEx( pHookItem->CallWndProc_hHook ); + /* Release the hook table entry */ + HeapFree(pHookItem->hHeap, 0, pHookItem ); + + return FALSE; +} + +/************************************************************************* + * OLEMenu_UnInstallHooks + * UnInstall thread scope message hooks for WH_GETMESSAGE and WH_CALLWNDPROC + * + * RETURNS: TRUE if message hooks were succesfully installed + * FALSE on failure + */ +BOOL OLEMenu_UnInstallHooks( DWORD tid ) +{ + OleMenuHookItem *pHookItem = NULL; + OleMenuHookItem **ppHook = &hook_list; + + while (*ppHook) + { + if ((*ppHook)->tid == tid) + { + pHookItem = *ppHook; + *ppHook = pHookItem->next; + break; + } + ppHook = &(*ppHook)->next; + } + if (!pHookItem) return FALSE; + + /* Uninstall the hooks installed for this thread */ + if ( !UnhookWindowsHookEx( pHookItem->GetMsg_hHook ) ) + goto CLEANUP; + if ( !UnhookWindowsHookEx( pHookItem->CallWndProc_hHook ) ) + goto CLEANUP; + + /* Release the hook table entry */ + HeapFree(pHookItem->hHeap, 0, pHookItem ); + + return TRUE; + +CLEANUP: + /* Release the hook table entry */ + if (pHookItem) + HeapFree(pHookItem->hHeap, 0, pHookItem ); + + return FALSE; +} + +/************************************************************************* + * OLEMenu_IsHookInstalled + * Tests if OLEMenu hooks have been installed for a thread + * + * RETURNS: The pointer and index of the hook table entry for the tid + * NULL and -1 for the index if no hooks were installed for this thread + */ +OleMenuHookItem * OLEMenu_IsHookInstalled( DWORD tid ) +{ + OleMenuHookItem *pHookItem = NULL; + + /* Do a simple linear search for an entry whose tid matches ours. + * We really need a map but efficiency is not a concern here. */ + for (pHookItem = hook_list; pHookItem; pHookItem = pHookItem->next) + { + if ( tid == pHookItem->tid ) + return pHookItem; + } + + return NULL; +} + +/*********************************************************************** + * OLEMenu_FindMainMenuIndex + * + * Used by OLEMenu API to find the top level group a menu item belongs to. + * On success pnPos contains the index of the item in the top level menu group + * + * RETURNS: TRUE if the ID was found, FALSE on failure + */ +static BOOL OLEMenu_FindMainMenuIndex( HMENU hMainMenu, HMENU hPopupMenu, UINT *pnPos ) +{ + UINT i, nItems; + + nItems = GetMenuItemCount( hMainMenu ); + + for (i = 0; i < nItems; i++) + { + HMENU hsubmenu; + + /* Is the current item a submenu? */ + if ( (hsubmenu = GetSubMenu(hMainMenu, i)) ) + { + /* If the handle is the same we're done */ + if ( hsubmenu == hPopupMenu ) + { + if (pnPos) + *pnPos = i; + return TRUE; + } + /* Recursively search without updating pnPos */ + else if ( OLEMenu_FindMainMenuIndex( hsubmenu, hPopupMenu, NULL ) ) + { + if (pnPos) + *pnPos = i; + return TRUE; + } + } + } + + return FALSE; +} + +/*********************************************************************** + * OLEMenu_SetIsServerMenu + * + * Checks whether a popup menu belongs to a shared menu group which is + * owned by the server, and sets the menu descriptor state accordingly. + * All menu messages from these groups should be routed to the server. + * + * RETURNS: TRUE if the popup menu is part of a server owned group + * FASE if the popup menu is part of a container owned group + */ +BOOL OLEMenu_SetIsServerMenu( HMENU hmenu, OleMenuDescriptor *pOleMenuDescriptor ) +{ + UINT nPos = 0, nWidth, i; + + pOleMenuDescriptor->bIsServerItem = FALSE; + + /* Don't bother searching if the popup is the combined menu itself */ + if ( hmenu == pOleMenuDescriptor->hmenuCombined ) + return FALSE; + + /* Find the menu item index in the shared OLE menu that this item belongs to */ + if ( !OLEMenu_FindMainMenuIndex( pOleMenuDescriptor->hmenuCombined, hmenu, &nPos ) ) + return FALSE; + + /* The group widths array has counts for the number of elements + * in the groups File, Edit, Container, Object, Window, Help. + * The Edit, Object & Help groups belong to the server object + * and the other three belong to the container. + * Loop thru the group widths and locate the group we are a member of. + */ + for ( i = 0, nWidth = 0; i < 6; i++ ) + { + nWidth += pOleMenuDescriptor->mgw.width[i]; + if ( nPos < nWidth ) + { + /* Odd elements are server menu widths */ + pOleMenuDescriptor->bIsServerItem = (i%2) ? TRUE : FALSE; + break; + } + } + + return pOleMenuDescriptor->bIsServerItem; +} + +/************************************************************************* + * OLEMenu_CallWndProc + * Thread scope WH_CALLWNDPROC hook proc filter function (callback) + * This is invoked from a message hook installed in OleSetMenuDescriptor. + */ +LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lParam) +{ #if 0 + LPCWPSTRUCT pMsg = NULL; + HOLEMENU hOleMenu = 0; + OleMenuDescriptor *pOleMenuDescriptor = NULL; + OleMenuHookItem *pHookItem = NULL; + WORD fuFlags; + + Print(MAX_TRACE, ("%i, %04x, %08x\n", code, wParam, (unsigned)lParam )); -WINOLEAPI OleQueryLinkFromData(IN LPDATAOBJECT pSrcDataObject){return S_OK;} -WINOLEAPI OleQueryCreateFromData(IN LPDATAOBJECT pSrcDataObject){return S_OK;} + /* Check if we're being asked to process the message */ + if ( HC_ACTION != code ) + goto NEXTHOOK; + + /* Retrieve the current message being dispatched from lParam */ + pMsg = (LPCWPSTRUCT)lParam; + /* Check if the message is destined for a window we are interested in: + * If the window has an OLEMenu property we may need to dispatch + * the menu message to its active objects window instead. */ -WINOLEAPI OleCreate(IN REFCLSID rclsid, IN REFIID riid, IN DWORD renderopt, - IN LPFORMATETC pFormatEtc, IN LPOLECLIENTSITE pClientSite, - IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} + hOleMenu = (HOLEMENU)GetPropA( pMsg->hwnd, "PROP_OLEMenuDescriptor" ); + if ( !hOleMenu ) + goto NEXTHOOK; -WINOLEAPI OleCreateEx(IN REFCLSID rclsid, IN REFIID riid, IN DWORD dwFlags, - IN DWORD renderopt, IN ULONG cFormats, IN DWORD* rgAdvf, - IN LPFORMATETC rgFormatEtc, IN IAdviseSink FAR* lpAdviseSink, - OUT DWORD FAR* rgdwConnection, IN LPOLECLIENTSITE pClientSite, - IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} + /* Get the menu descriptor */ + pOleMenuDescriptor = (OleMenuDescriptor *) GlobalLock( hOleMenu ); + if ( !pOleMenuDescriptor ) /* Bad descriptor! */ + goto NEXTHOOK; -WINOLEAPI OleCreateFromData(IN LPDATAOBJECT pSrcDataObj, IN REFIID riid, - IN DWORD renderopt, IN LPFORMATETC pFormatEtc, - IN LPOLECLIENTSITE pClientSite, IN LPSTORAGE pStg, - OUT LPVOID FAR* ppvObj){return S_OK;} + /* Process menu messages */ + switch( pMsg->message ) + { + case WM_INITMENU: + { + /* Reset the menu descriptor state */ + pOleMenuDescriptor->bIsServerItem = FALSE; -WINOLEAPI OleCreateFromDataEx(IN LPDATAOBJECT pSrcDataObj, IN REFIID riid, - IN DWORD dwFlags, IN DWORD renderopt, IN ULONG cFormats, IN DWORD* rgAdvf, - IN LPFORMATETC rgFormatEtc, IN IAdviseSink FAR* lpAdviseSink, - OUT DWORD FAR* rgdwConnection, IN LPOLECLIENTSITE pClientSite, - IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} + /* Send this message to the server as well */ + SendMessageA( pOleMenuDescriptor->hwndActiveObject, + pMsg->message, pMsg->wParam, pMsg->lParam ); + goto NEXTHOOK; + } + + case WM_INITMENUPOPUP: + { + /* Save the state for whether this is a server owned menu */ + OLEMenu_SetIsServerMenu( (HMENU)pMsg->wParam, pOleMenuDescriptor ); + break; + } + + case WM_MENUSELECT: + { + fuFlags = HIWORD(pMsg->wParam); /* Get flags */ + if ( fuFlags & MF_SYSMENU ) + goto NEXTHOOK; -WINOLEAPI OleCreateLinkFromData(IN LPDATAOBJECT pSrcDataObj, IN REFIID riid, - IN DWORD renderopt, IN LPFORMATETC pFormatEtc, - IN LPOLECLIENTSITE pClientSite, IN LPSTORAGE pStg, - OUT LPVOID FAR* ppvObj){return S_OK;} + /* Save the state for whether this is a server owned popup menu */ + else if ( fuFlags & MF_POPUP ) + OLEMenu_SetIsServerMenu( (HMENU)pMsg->lParam, pOleMenuDescriptor ); -WINOLEAPI OleCreateLinkFromDataEx(IN LPDATAOBJECT pSrcDataObj, IN REFIID riid, - IN DWORD dwFlags, IN DWORD renderopt, IN ULONG cFormats, IN DWORD* rgAdvf, - IN LPFORMATETC rgFormatEtc, IN IAdviseSink FAR* lpAdviseSink, - OUT IN DWORD FAR* rgdwConnection, IN LPOLECLIENTSITE pClientSite, - IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} + break; + } + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) pMsg->lParam; + if ( pMsg->wParam != 0 || lpdis->CtlType != ODT_MENU ) + goto NEXTHOOK; /* Not a menu message */ -WINOLEAPI OleCreateStaticFromData(IN LPDATAOBJECT pSrcDataObj, IN REFIID iid, - IN DWORD renderopt, IN LPFORMATETC pFormatEtc, - IN LPOLECLIENTSITE pClientSite, IN LPSTORAGE pStg, - OUT LPVOID FAR* ppvObj){return S_OK;} + break; + } + default: + goto NEXTHOOK; + } -WINOLEAPI OleCreateLink(IN LPMONIKER pmkLinkSrc, IN REFIID riid, - IN DWORD renderopt, IN LPFORMATETC lpFormatEtc, - IN LPOLECLIENTSITE pClientSite, IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} + /* If the message was for the server dispatch it accordingly */ + if ( pOleMenuDescriptor->bIsServerItem ) + { + SendMessageA( pOleMenuDescriptor->hwndActiveObject, + pMsg->message, pMsg->wParam, pMsg->lParam ); + } + +NEXTHOOK: + if ( pOleMenuDescriptor ) + GlobalUnlock( hOleMenu ); + + /* Lookup the hook item for the current thread */ + if ( !( pHookItem = OLEMenu_IsHookInstalled( GetCurrentThreadId() ) ) ) + { + /* This should never fail!! */ + Print(MID_TRACE, ("could not retrieve hHook for current thread!\n" )); + return 0; + } + + /* Pass on the message to the next hooker */ + return CallNextHookEx( pHookItem->CallWndProc_hHook, code, wParam, lParam ); -WINOLEAPI OleCreateLinkEx(IN LPMONIKER pmkLinkSrc, IN REFIID riid, - IN DWORD dwFlags, IN DWORD renderopt, IN ULONG cFormats, IN DWORD* rgAdvf, - IN LPFORMATETC rgFormatEtc, IN IAdviseSink FAR* lpAdviseSink, - OUT DWORD FAR* rgdwConnection, IN LPOLECLIENTSITE pClientSite, - IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} +#else + UNIMPLEMENTED; + return 0; +#endif +} -WINOLEAPI OleCreateLinkToFile(IN LPCOLESTR lpszFileName, IN REFIID riid, - IN DWORD renderopt, IN LPFORMATETC lpFormatEtc, - IN LPOLECLIENTSITE pClientSite, IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} +/************************************************************************* + * OLEMenu_GetMsgProc + * Thread scope WH_GETMESSAGE hook proc filter function (callback) + * This is invoked from a message hook installed in OleSetMenuDescriptor. + */ +LRESULT CALLBACK OLEMenu_GetMsgProc(INT code, WPARAM wParam, LPARAM lParam) +{ + LPMSG pMsg = NULL; + HOLEMENU hOleMenu = 0; + OleMenuDescriptor *pOleMenuDescriptor = NULL; + OleMenuHookItem *pHookItem = NULL; + WORD wCode; + + Print(MAX_TRACE, ("%i, %04x, %08x\n", code, wParam, (unsigned)lParam )); -WINOLEAPI OleCreateLinkToFileEx(IN LPCOLESTR lpszFileName, IN REFIID riid, - IN DWORD dwFlags, IN DWORD renderopt, IN ULONG cFormats, IN DWORD* rgAdvf, - IN LPFORMATETC rgFormatEtc, IN IAdviseSink FAR* lpAdviseSink, - OUT DWORD FAR* rgdwConnection, IN LPOLECLIENTSITE pClientSite, - IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} + /* Check if we're being asked to process a messages */ + if ( HC_ACTION != code ) + goto NEXTHOOK; + + /* Retrieve the current message being dispatched from lParam */ + pMsg = (LPMSG)lParam; -WINOLEAPI OleCreateFromFile(IN REFCLSID rclsid, IN LPCOLESTR lpszFileName, IN REFIID riid, - IN DWORD renderopt, IN LPFORMATETC lpFormatEtc, - IN LPOLECLIENTSITE pClientSite, IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} + /* Check if the message is destined for a window we are interested in: + * If the window has an OLEMenu property we may need to dispatch + * the menu message to its active objects window instead. */ -WINOLEAPI OleCreateFromFileEx(IN REFCLSID rclsid, IN LPCOLESTR lpszFileName, IN REFIID riid, - IN DWORD dwFlags, IN DWORD renderopt, IN ULONG cFormats, IN DWORD* rgAdvf, - IN LPFORMATETC rgFormatEtc, IN IAdviseSink FAR* lpAdviseSink, - OUT DWORD FAR* rgdwConnection, IN LPOLECLIENTSITE pClientSite, - IN LPSTORAGE pStg, OUT LPVOID FAR* ppvObj){return S_OK;} + hOleMenu = (HOLEMENU)GetPropA( pMsg->hwnd, "PROP_OLEMenuDescriptor" ); + if ( !hOleMenu ) + goto NEXTHOOK; -WINOLEAPI OleLoad(IN LPSTORAGE pStg, IN REFIID riid, IN LPOLECLIENTSITE pClientSite, - OUT LPVOID FAR* ppvObj){return S_OK;} + /* Process menu messages */ + switch( pMsg->message ) + { + case WM_COMMAND: + { + wCode = HIWORD(pMsg->wParam); /* Get notification code */ + if ( wCode ) + goto NEXTHOOK; /* Not a menu message */ + break; + } + default: + goto NEXTHOOK; + } -WINOLEAPI OleSave(IN LPPERSISTSTORAGE pPS, IN LPSTORAGE pStg, IN BOOL fSameAsLoad){return S_OK;} + /* Get the menu descriptor */ + pOleMenuDescriptor = (OleMenuDescriptor *) GlobalLock( hOleMenu ); + if ( !pOleMenuDescriptor ) /* Bad descriptor! */ + goto NEXTHOOK; -WINOLEAPI OleLoadFromStream( IN LPSTREAM pStm, IN REFIID iidInterface, OUT LPVOID FAR* ppvObj){return S_OK;} -WINOLEAPI OleSaveToStream( IN LPPERSISTSTREAM pPStm, IN LPSTREAM pStm ){return S_OK;} + /* If the message was for the server dispatch it accordingly */ + if ( pOleMenuDescriptor->bIsServerItem ) + { + /* Change the hWnd in the message to the active objects hWnd. + * The message loop which reads this message will automatically + * dispatch it to the embedded objects window. */ + pMsg->hwnd = pOleMenuDescriptor->hwndActiveObject; + } + +NEXTHOOK: + if ( pOleMenuDescriptor ) + GlobalUnlock( hOleMenu ); + + /* Lookup the hook item for the current thread */ + if ( !( pHookItem = OLEMenu_IsHookInstalled( GetCurrentThreadId() ) ) ) + { + /* This should never fail!! */ + Print(MID_TRACE, ("could not retrieve hHook for current thread!\n" )); + return FALSE; + } + + /* Pass on the message to the next hooker */ + return CallNextHookEx( pHookItem->GetMsg_hHook, code, wParam, lParam ); +} +/*********************************************************************** + * OleCreateMenuDescriptor [OLE32.97] + * Creates an OLE menu descriptor for OLE to use when dispatching + * menu messages and commands. + * + * PARAMS: + * hmenuCombined - Handle to the objects combined menu + * lpMenuWidths - Pointer to array of 6 LONG's indicating menus per group + * + */ +HOLEMENU WINAPI OleCreateMenuDescriptor( + HMENU hmenuCombined, + LPOLEMENUGROUPWIDTHS lpMenuWidths) +{ + HOLEMENU hOleMenu; + OleMenuDescriptor *pOleMenuDescriptor; + int i; -WINOLEAPI OleSetContainedObject(IN LPUNKNOWN pUnknown, IN BOOL fContained){return S_OK;} -WINOLEAPI OleNoteObjectVisible(IN LPUNKNOWN pUnknown, IN BOOL fVisible){return S_OK;} + if ( !hmenuCombined || !lpMenuWidths ) + return 0; + /* Create an OLE menu descriptor */ + if ( !(hOleMenu = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, + sizeof(OleMenuDescriptor) ) ) ) + return 0; + pOleMenuDescriptor = (OleMenuDescriptor *) GlobalLock( hOleMenu ); + if ( !pOleMenuDescriptor ) + return 0; -WINOLEAPI RegisterDragDrop(IN HWND hwnd, IN LPDROPTARGET pDropTarget){return S_OK;} -WINOLEAPI RevokeDragDrop(IN HWND hwnd){return S_OK;} -WINOLEAPI DoDragDrop(IN LPDATAOBJECT pDataObj, IN LPDROPSOURCE pDropSource, - IN DWORD dwOKEffects, OUT LPDWORD pdwEffect){return S_OK;} + /* Initialize menu group widths and hmenu */ + for ( i = 0; i < 6; i++ ) + pOleMenuDescriptor->mgw.width[i] = lpMenuWidths->width[i]; + + pOleMenuDescriptor->hmenuCombined = hmenuCombined; + pOleMenuDescriptor->bIsServerItem = FALSE; + GlobalUnlock( hOleMenu ); + + return hOleMenu; +} +/*********************************************************************** + * OleDestroyMenuDescriptor [OLE32.99] + * Destroy the shared menu descriptor + */ +HRESULT WINAPI OleDestroyMenuDescriptor( + HOLEMENU hmenuDescriptor) +{ + if ( hmenuDescriptor ) + GlobalFree( hmenuDescriptor ); + return S_OK; +} -WINOLEAPI OleSetClipboard(IN LPDATAOBJECT pDataObj){return S_OK;} -WINOLEAPI OleGetClipboard(OUT LPDATAOBJECT FAR* ppDataObj){return S_OK;} -WINOLEAPI OleFlushClipboard(void){return S_OK;} -WINOLEAPI OleIsCurrentClipboard(IN LPDATAOBJECT pDataObj){return S_OK;} +/*********************************************************************** + * OleSetMenuDescriptor [OLE32.129] + * Installs or removes OLE dispatching code for the containers frame window + * FIXME: The lpFrame and lpActiveObject parameters are currently ignored + * OLE should install context sensitive help F1 filtering for the app when + * these are non null. + * + * PARAMS: + * hOleMenu Handle to composite menu descriptor + * hwndFrame Handle to containers frame window + * hwndActiveObject Handle to objects in-place activation window + * lpFrame Pointer to IOleInPlaceFrame on containers window + * lpActiveObject Pointer to IOleInPlaceActiveObject on active in-place object + * + * RETURNS: + * S_OK - menu installed correctly + * E_FAIL, E_INVALIDARG, E_UNEXPECTED - failure + */ +HRESULT WINAPI OleSetMenuDescriptor( + HOLEMENU hOleMenu, + HWND hwndFrame, + HWND hwndActiveObject, + LPOLEINPLACEFRAME lpFrame, + LPOLEINPLACEACTIVEOBJECT lpActiveObject) +{ + OleMenuDescriptor *pOleMenuDescriptor = NULL; + /* Check args */ + if ( !hwndFrame || (hOleMenu && !hwndActiveObject) ) + return E_INVALIDARG; -WINOLEAPI_(HOLEMENU) OleCreateMenuDescriptor (IN HMENU hmenuCombined, - IN LPOLEMENUGROUPWIDTHS lpMenuWidths){return NULL;} -WINOLEAPI OleSetMenuDescriptor (IN HOLEMENU holemenu, IN HWND hwndFrame, - IN HWND hwndActiveObject, - IN LPOLEINPLACEFRAME lpFrame, - IN LPOLEINPLACEACTIVEOBJECT lpActiveObj){return S_OK;} -WINOLEAPI OleDestroyMenuDescriptor (IN HOLEMENU holemenu){return S_OK;} + if ( lpFrame || lpActiveObject ) + { + Print(MIN_TRACE, ("(%x, %x, %x, %p, %p), Context sensitive help filtering not implemented!\n", + (unsigned int)hOleMenu, + hwndFrame, + hwndActiveObject, + lpFrame, + lpActiveObject)); + } -WINOLEAPI OleTranslateAccelerator (IN LPOLEINPLACEFRAME lpFrame, - IN LPOLEINPLACEFRAMEINFO lpFrameInfo, IN LPMSG lpmsg){return S_OK;} + /* Set up a message hook to intercept the containers frame window messages. + * The message filter is responsible for dispatching menu messages from the + * shared menu which are intended for the object. + */ + if ( hOleMenu ) /* Want to install dispatching code */ + { + /* If OLEMenu hooks are already installed for this thread, fail + * Note: This effectively means that OleSetMenuDescriptor cannot + * be called twice in succession on the same frame window + * without first calling it with a null hOleMenu to uninstall */ + if ( OLEMenu_IsHookInstalled( GetCurrentThreadId() ) ) + return E_FAIL; + + /* Get the menu descriptor */ + pOleMenuDescriptor = (OleMenuDescriptor *) GlobalLock( hOleMenu ); + if ( !pOleMenuDescriptor ) + return E_UNEXPECTED; -WINOLEAPI_(HANDLE) OleDuplicateData (IN HANDLE hSrc, IN CLIPFORMAT cfFormat, - IN UINT uiFlags){return NULL;} + /* Update the menu descriptor */ + pOleMenuDescriptor->hwndFrame = hwndFrame; + pOleMenuDescriptor->hwndActiveObject = hwndActiveObject; -WINOLEAPI OleDraw (IN LPUNKNOWN pUnknown, IN DWORD dwAspect, IN HDC hdcDraw, - IN LPCRECT lprcBounds){return S_OK;} + GlobalUnlock( hOleMenu ); + pOleMenuDescriptor = NULL; + + /* Add a menu descriptor windows property to the frame window */ + SetPropA( hwndFrame, "PROP_OLEMenuDescriptor", hOleMenu ); -WINOLEAPI OleRun(IN LPUNKNOWN pUnknown){return S_OK;} -WINOLEAPI_(BOOL) OleIsRunning(IN LPOLEOBJECT pObject){return S_OK;} -WINOLEAPI OleLockRunning(IN LPUNKNOWN pUnknown, IN BOOL fLock, IN BOOL fLastUnlockCloses){return S_OK;} -WINOLEAPI_(void) ReleaseStgMedium(IN LPSTGMEDIUM){return;} -WINOLEAPI CreateOleAdviseHolder(OUT LPOLEADVISEHOLDER FAR* ppOAHolder){return S_OK;} + /* Install thread scope message hooks for WH_GETMESSAGE and WH_CALLWNDPROC */ + if ( !OLEMenu_InstallHooks( GetCurrentThreadId() ) ) + return E_FAIL; + } + else /* Want to uninstall dispatching code */ + { + /* Uninstall the hooks */ + if ( !OLEMenu_UnInstallHooks( GetCurrentThreadId() ) ) + return E_FAIL; + + /* Remove the menu descriptor property from the frame window */ + RemovePropA( hwndFrame, "PROP_OLEMenuDescriptor" ); + } + + return S_OK; +} -WINOLEAPI OleCreateDefaultHandler(IN REFCLSID clsid, IN LPUNKNOWN pUnkOuter, - IN REFIID riid, OUT LPVOID FAR* lplpObj){return S_OK;} +/****************************************************************************** + * IsAccelerator [OLE32.75] + * Mostly copied from controls/menu.c TranslateAccelerator implementation + */ +BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* lpwCmd) +{ +#if 0 + /* YES, Accel16! */ + LPACCEL16 lpAccelTbl; + int i; -WINOLEAPI OleCreateEmbeddingHelper(IN REFCLSID clsid, IN LPUNKNOWN pUnkOuter, - IN DWORD flags, IN LPCLASSFACTORY pCF, - IN REFIID riid, OUT LPVOID FAR* lplpObj){return S_OK;} + if(!lpMsg) return FALSE; + if (!hAccel || !(lpAccelTbl = (LPACCEL16)LockResource16(hAccel))) + { + WARN_(accel)("invalid accel handle=%04x\n", hAccel); + return FALSE; + } + if((lpMsg->message != WM_KEYDOWN && + lpMsg->message != WM_KEYUP && + lpMsg->message != WM_SYSKEYDOWN && + lpMsg->message != WM_SYSKEYUP && + lpMsg->message != WM_CHAR)) return FALSE; -WINOLEAPI_(BOOL) IsAccelerator(IN HACCEL hAccel, IN int cAccelEntries, IN LPMSG lpMsg, - OUT WORD FAR* lpwCmd){return S_OK;} + Print(MAX_TRACE, ("hAccel=%04x, cAccelEntries=%d," + "msg->hwnd=%04x, msg->message=%04x, wParam=%08x, lParam=%08lx\n", + hAccel, cAccelEntries, + lpMsg->hwnd, lpMsg->message, lpMsg->wParam, lpMsg->lParam)); + for(i = 0; i < cAccelEntries; i++) + { + if(lpAccelTbl[i].key != lpMsg->wParam) + continue; -WINOLEAPI_(HGLOBAL) OleGetIconOfFile(IN LPOLESTR lpszPath, IN BOOL fUseFileAsLabel){return NULL;} + if(lpMsg->message == WM_CHAR) + { + if(!(lpAccelTbl[i].fVirt & FALT) && !(lpAccelTbl[i].fVirt & FVIRTKEY)) + { + Print(MAX_TRACE, ("found accel for WM_CHAR: ('%c')\n", lpMsg->wParam & 0xff)); + goto found; + } + } + else + { + if(lpAccelTbl[i].fVirt & FVIRTKEY) + { + INT mask = 0; + Print(MAX_TRACE, ("found accel for virt_key %04x (scan %04x)\n", + lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff)); + if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT; + if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL; + if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT; + if(mask == (lpAccelTbl[i].fVirt & (FSHIFT | FCONTROL | FALT))) goto found; + Print(MAX_TRACE, ("incorrect SHIFT/CTRL/ALT-state\n")); + } + else + { + if(!(lpMsg->lParam & 0x01000000)) /* no special_key */ + { + if((lpAccelTbl[i].fVirt & FALT) && (lpMsg->lParam & 0x20000000)) + { /* ^^ ALT pressed */ + Print(MAX_TRACE, ("found accel for Alt-%c\n", lpMsg->wParam & 0xff)); + goto found; + } + } + } + } + } -WINOLEAPI_(HGLOBAL) OleGetIconOfClass(IN REFCLSID rclsid, IN LPOLESTR lpszLabel, - IN BOOL fUseTypeAsLabel){return NULL;} + WARN_(accel)("couldn't translate accelerator key\n"); + return FALSE; -WINOLEAPI_(HGLOBAL) OleMetafilePictFromIconAndLabel(IN HICON hIcon, IN LPOLESTR lpszLabel, - IN LPOLESTR lpszSourceFile, IN UINT iIconIndex){return NULL;} +found: + if(lpwCmd) *lpwCmd = lpAccelTbl[i].cmd; + return TRUE; +#else + return FALSE; +#endif +} +/*********************************************************************** + * ReleaseStgMedium [OLE32.140] + */ +void WINAPI ReleaseStgMedium( + STGMEDIUM* pmedium) +{ + switch (pmedium->tymed) + { + case TYMED_HGLOBAL: + { + if ( (pmedium->pUnkForRelease==0) && + (pmedium->u.hGlobal!=0) ) + GlobalFree(pmedium->u.hGlobal); + pmedium->u.hGlobal = 0; + break; + } + case TYMED_FILE: + { + if (pmedium->u.lpszFileName!=0) + { + if (pmedium->pUnkForRelease==0) + { + DeleteFileW(pmedium->u.lpszFileName); + } + + CoTaskMemFree(pmedium->u.lpszFileName); + } -WINOLEAPI OleRegGetUserType (IN REFCLSID clsid, IN DWORD dwFormOfType, - OUT LPOLESTR FAR* pszUserType){return S_OK;} + pmedium->u.lpszFileName = 0; + break; + } + case TYMED_ISTREAM: + { + if (pmedium->u.pstm!=0) + { + IStream_Release(pmedium->u.pstm); + } -WINOLEAPI OleRegGetMiscStatus (IN REFCLSID clsid, IN DWORD dwAspect, - OUT DWORD FAR* pdwStatus){return S_OK;} + pmedium->u.pstm = 0; + break; + } + case TYMED_ISTORAGE: + { + if (pmedium->u.pstg!=0) + { + IStorage_Release(pmedium->u.pstg); + } -WINOLEAPI OleRegEnumFormatEtc (IN REFCLSID clsid, IN DWORD dwDirection, - OUT LPENUMFORMATETC FAR* ppenum){return S_OK;} + pmedium->u.pstg = 0; + break; + } + case TYMED_GDI: + { + if ( (pmedium->pUnkForRelease==0) && + (pmedium->u.hGlobal!=0) ) + DeleteObject(pmedium->u.hGlobal); -WINOLEAPI OleRegEnumVerbs (IN REFCLSID clsid, OUT LPENUMOLEVERB FAR* ppenum){return S_OK;} + pmedium->u.hGlobal = 0; + break; + } + case TYMED_MFPICT: + { + if ( (pmedium->pUnkForRelease==0) && + (pmedium->u.hMetaFilePict!=0) ) + { +#if 0 + LPMETAFILEPICT pMP = GlobalLock(pmedium->u.hMetaFilePict); + DeleteMetaFile(pMP->hMF); +#else + Print(MIN_TRACE, ("Depending on MetaFile implementation\n")); +#endif + GlobalUnlock(pmedium->u.hMetaFilePict); + GlobalFree(pmedium->u.hMetaFilePict); + } + pmedium->u.hMetaFilePict = 0; + break; + } + case TYMED_ENHMF: + { + if ( (pmedium->pUnkForRelease==0) && + (pmedium->u.hEnhMetaFile!=0) ) + { + DeleteEnhMetaFile(pmedium->u.hEnhMetaFile); + } -// OLE 1.0 -WINOLEAPI OleConvertOLESTREAMToIStorage - (IN LPOLESTREAM lpolestream, - OUT LPSTORAGE pstg, - IN const DVTARGETDEVICE FAR* ptd){return S_OK;} + pmedium->u.hEnhMetaFile = 0; + break; + } + case TYMED_NULL: + default: + break; + } -WINOLEAPI OleConvertIStorageToOLESTREAM - (IN LPSTORAGE pstg, - OUT LPOLESTREAM lpolestream){return S_OK;} + /* + * After cleaning up, the unknown is released + */ + if (pmedium->pUnkForRelease!=0) + { + IUnknown_Release(pmedium->pUnkForRelease); + pmedium->pUnkForRelease = 0; + } +} +/*** + * OLEDD_Initialize() + * + * Initializes the OLE drag and drop data structures. + */ +static void OLEDD_Initialize() +{ + WNDCLASS wndClass; -WINOLEAPI GetHGlobalFromILockBytes (IN LPLOCKBYTES plkbyt, OUT HGLOBAL FAR* phglobal){return S_OK;} -WINOLEAPI CreateILockBytesOnHGlobal (IN HGLOBAL hGlobal, IN BOOL fDeleteOnRelease, - OUT LPLOCKBYTES FAR* pplkbyt){return S_OK;} + ZeroMemory (&wndClass, sizeof(WNDCLASS)); + wndClass.style = CS_GLOBALCLASS; + wndClass.lpfnWndProc = (WNDPROC)OLEDD_DragTrackerWindowProc; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = sizeof(TrackerWindowInfo*); + wndClass.hCursor = 0; + wndClass.hbrBackground = 0; + wndClass.lpszClassName = OLEDD_DRAGTRACKERCLASS; + + RegisterClassA (&wndClass); +} -WINOLEAPI GetHGlobalFromStream (IN LPSTREAM pstm, OUT HGLOBAL FAR* phglobal){return S_OK;} -WINOLEAPI CreateStreamOnHGlobal (IN HGLOBAL hGlobal, IN BOOL fDeleteOnRelease, - OUT LPSTREAM FAR* ppstm){return S_OK;} +/*** + * OLEDD_UnInitialize() + * + * Releases the OLE drag and drop data structures. + */ +static void OLEDD_UnInitialize() +{ + /* + * Simply empty the list. + */ + while (targetListHead!=NULL) + { + RevokeDragDrop(targetListHead->hwndTarget); + } +} +/*** + * OLEDD_InsertDropTarget() + * + * Insert the target node in the tree. + */ +static void OLEDD_InsertDropTarget(DropTargetNode* nodeToAdd) +{ + DropTargetNode* curNode; + DropTargetNode** parentNodeLink; + /* + * Iterate the tree to find the insertion point. + */ + curNode = targetListHead; + parentNodeLink = &targetListHead; -WINOLEAPI OleDoAutoConvert(IN LPSTORAGE pStg, OUT LPCLSID pClsidNew){return S_OK;} -WINOLEAPI OleGetAutoConvert(IN REFCLSID clsidOld, OUT LPCLSID pClsidNew){return S_OK;} -WINOLEAPI OleSetAutoConvert(IN REFCLSID clsidOld, IN REFCLSID clsidNew){return S_OK;} -WINOLEAPI GetConvertStg(IN LPSTORAGE pStg){return S_OK;} -WINOLEAPI SetConvertStg(IN LPSTORAGE pStg, IN BOOL fConvert){return S_OK;} + while (curNode!=NULL) + { + if (nodeToAdd->hwndTargethwndTarget) + { + /* + * If the node we want to add has a smaller HWND, go left + */ + parentNodeLink = &curNode->prevDropTarget; + curNode = curNode->prevDropTarget; + } + else if (nodeToAdd->hwndTarget>curNode->hwndTarget) + { + /* + * If the node we want to add has a larger HWND, go right + */ + parentNodeLink = &curNode->nextDropTarget; + curNode = curNode->nextDropTarget; + } + else + { + /* + * The item was found in the list. It shouldn't have been there + */ + assert(FALSE); + return; + } + } + /* + * If we get here, we have found a spot for our item. The parentNodeLink + * pointer points to the pointer that we have to modify. + * The curNode should be NULL. We just have to establish the link and Voila! + */ + assert(curNode==NULL); + assert(parentNodeLink!=NULL); + assert(*parentNodeLink==NULL); -WINOLEAPI OleConvertIStorageToOLESTREAMEx - (IN LPSTORAGE pstg, - // Presentation data to OLESTREAM - IN CLIPFORMAT cfFormat, // format - IN LONG lWidth, // width - IN LONG lHeight, // height - IN DWORD dwSize, // size in bytes - IN LPSTGMEDIUM pmedium, // bits - OUT LPOLESTREAM polestm){return S_OK;} + *parentNodeLink=nodeToAdd; +} -WINOLEAPI OleConvertOLESTREAMToIStorageEx - (IN LPOLESTREAM polestm, - OUT LPSTORAGE pstg, - // Presentation data from OLESTREAM - OUT CLIPFORMAT FAR* pcfFormat, // format - OUT LONG FAR* plwWidth, // width - OUT LONG FAR* plHeight, // height - OUT DWORD FAR* pdwSize, // size in bytes - OUT LPSTGMEDIUM pmedium){return S_OK;} // bits +/*** + * OLEDD_ExtractDropTarget() + * + * Removes the target node from the tree. + */ +static DropTargetNode* OLEDD_ExtractDropTarget(HWND hwndOfTarget) +{ + DropTargetNode* curNode; + DropTargetNode** parentNodeLink; + + /* + * Iterate the tree to find the insertion point. + */ + curNode = targetListHead; + parentNodeLink = &targetListHead; + + while (curNode!=NULL) + { + if (hwndOfTargethwndTarget) + { + /* + * If the node we want to add has a smaller HWND, go left + */ + parentNodeLink = &curNode->prevDropTarget; + curNode = curNode->prevDropTarget; + } + else if (hwndOfTarget>curNode->hwndTarget) + { + /* + * If the node we want to add has a larger HWND, go right + */ + parentNodeLink = &curNode->nextDropTarget; + curNode = curNode->nextDropTarget; + } + else + { + /* + * The item was found in the list. Detach it from it's parent and + * re-insert it's kids in the tree. + */ + assert(parentNodeLink!=NULL); + assert(*parentNodeLink==curNode); + + /* + * We arbitrately re-attach the left sub-tree to the parent. + */ + *parentNodeLink = curNode->prevDropTarget; + + /* + * And we re-insert the right subtree + */ + if (curNode->nextDropTarget!=NULL) + { + OLEDD_InsertDropTarget(curNode->nextDropTarget); + } + + /* + * The node we found is still a valid node once we complete + * the unlinking of the kids. + */ + curNode->nextDropTarget=NULL; + curNode->prevDropTarget=NULL; + + return curNode; + } + } + + /* + * If we get here, the node is not in the tree + */ + return NULL; +} + +/*** + * OLEDD_FindDropTarget() + * + * Finds information about the drop target. + */ +static DropTargetNode* OLEDD_FindDropTarget(HWND hwndOfTarget) +{ + DropTargetNode* curNode; + + /* + * Iterate the tree to find the HWND value. + */ + curNode = targetListHead; + + while (curNode!=NULL) + { + if (hwndOfTargethwndTarget) + { + /* + * If the node we want to add has a smaller HWND, go left + */ + curNode = curNode->prevDropTarget; + } + else if (hwndOfTarget>curNode->hwndTarget) + { + /* + * If the node we want to add has a larger HWND, go right + */ + curNode = curNode->nextDropTarget; + } + else + { + /* + * The item was found in the list. + */ + return curNode; + } + } + + /* + * If we get here, the item is not in the list + */ + return NULL; +} + +/*** + * OLEDD_DragTrackerWindowProc() + * + * This method is the WindowProcedure of the drag n drop tracking + * window. During a drag n Drop operation, an invisible window is created + * to receive the user input and act upon it. This procedure is in charge + * of this behavior. + */ +static LRESULT WINAPI OLEDD_DragTrackerWindowProc( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_CREATE: + { + LPCREATESTRUCT createStruct = (LPCREATESTRUCT)lParam; + + SetWindowLongA(hwnd, 0, (LONG)createStruct->lpCreateParams); + + + break; + } + case WM_MOUSEMOVE: + { + TrackerWindowInfo* trackerInfo = (TrackerWindowInfo*)GetWindowLongA(hwnd, 0); + POINT mousePos; + + /* + * Get the current mouse position in screen coordinates. + */ + mousePos.x = LOWORD(lParam); + mousePos.y = HIWORD(lParam); + ClientToScreen(hwnd, &mousePos); + + /* + * Track the movement of the mouse. + */ + OLEDD_TrackMouseMove(trackerInfo, mousePos, wParam); + + break; + } + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + { + TrackerWindowInfo* trackerInfo = (TrackerWindowInfo*)GetWindowLongA(hwnd, 0); + POINT mousePos; + + /* + * Get the current mouse position in screen coordinates. + */ + mousePos.x = LOWORD(lParam); + mousePos.y = HIWORD(lParam); + ClientToScreen(hwnd, &mousePos); + + /* + * Notify everyone that the button state changed + * TODO: Check if the "escape" key was pressed. + */ + OLEDD_TrackStateChange(trackerInfo, mousePos, wParam); + + break; + } + } + + /* + * This is a window proc after all. Let's call the default. + */ + return DefWindowProcA (hwnd, uMsg, wParam, lParam); +} + +/*** + * OLEDD_TrackMouseMove() + * + * This method is invoked while a drag and drop operation is in effect. + * it will generate the appropriate callbacks in the drop source + * and drop target. It will also provide the expected feedback to + * the user. + * + * params: + * trackerInfo - Pointer to the structure identifying the + * drag & drop operation that is currently + * active. + * mousePos - Current position of the mouse in screen + * coordinates. + * keyState - Contains the state of the shift keys and the + * mouse buttons (MK_LBUTTON and the like) + */ +static void OLEDD_TrackMouseMove( + TrackerWindowInfo* trackerInfo, + POINT mousePos, + DWORD keyState) +{ + HWND hwndNewTarget = 0; + HRESULT hr = S_OK; + + /* + * Get the handle of the window under the mouse + */ + hwndNewTarget = WindowFromPoint(mousePos); + + /* + * Every time, we re-initialize the effects passed to the + * IDropTarget to the effects allowed by the source. + */ + *trackerInfo->pdwEffect = trackerInfo->dwOKEffect; + + /* + * If we are hovering over the same target as before, send the + * DragOver notification + */ + if ( (trackerInfo->curDragTarget != 0) && + (trackerInfo->curDragTargetHWND==hwndNewTarget) ) + { + POINTL mousePosParam; + + /* + * The documentation tells me that the coordinate should be in the target + * window's coordinate space. However, the tests I made tell me the + * coordinates should be in screen coordinates. + */ + mousePosParam.x = mousePos.x; + mousePosParam.y = mousePos.y; + + IDropTarget_DragOver(trackerInfo->curDragTarget, + keyState, + mousePosParam, + trackerInfo->pdwEffect); + } + else + { + DropTargetNode* newDropTargetNode = 0; + + /* + * If we changed window, we have to notify our old target and check for + * the new one. + */ + if (trackerInfo->curDragTarget!=0) + { + IDropTarget_DragLeave(trackerInfo->curDragTarget); + } + + /* + * Make sure we're hovering over a window. + */ + if (hwndNewTarget!=0) + { + /* + * Find-out if there is a drag target under the mouse + */ + HWND nexttar = hwndNewTarget; + do { + newDropTargetNode = OLEDD_FindDropTarget(nexttar); + } while (!newDropTargetNode && (nexttar = GetParent(nexttar)) != 0); + if(nexttar) hwndNewTarget = nexttar; + + trackerInfo->curDragTargetHWND = hwndNewTarget; + trackerInfo->curDragTarget = newDropTargetNode ? newDropTargetNode->dropTarget : 0; + + /* + * If there is, notify it that we just dragged-in + */ + if (trackerInfo->curDragTarget!=0) + { + POINTL mousePosParam; + + /* + * The documentation tells me that the coordinate should be in the target + * window's coordinate space. However, the tests I made tell me the + * coordinates should be in screen coordinates. + */ + mousePosParam.x = mousePos.x; + mousePosParam.y = mousePos.y; + + IDropTarget_DragEnter(trackerInfo->curDragTarget, + trackerInfo->dataObject, + keyState, + mousePosParam, + trackerInfo->pdwEffect); + } + } + else + { + /* + * The mouse is not over a window so we don't track anything. + */ + trackerInfo->curDragTargetHWND = 0; + trackerInfo->curDragTarget = 0; + } + } + + /* + * Now that we have done that, we have to tell the source to give + * us feedback on the work being done by the target. If we don't + * have a target, simulate no effect. + */ + if (trackerInfo->curDragTarget==0) + { + *trackerInfo->pdwEffect = DROPEFFECT_NONE; + } + + hr = IDropSource_GiveFeedback(trackerInfo->dropSource, + *trackerInfo->pdwEffect); + + /* + * When we ask for feedback from the drop source, sometimes it will + * do all the necessary work and sometimes it will not handle it + * when that's the case, we must display the standard drag and drop + * cursors. + */ + if (hr==DRAGDROP_S_USEDEFAULTCURSORS) + { + if (*trackerInfo->pdwEffect & DROPEFFECT_MOVE) + { + SetCursor(LoadCursorA(OLE32_hInstance, MAKEINTRESOURCE(1))); + } + else if (*trackerInfo->pdwEffect & DROPEFFECT_COPY) + { + SetCursor(LoadCursorA(OLE32_hInstance, MAKEINTRESOURCE(2))); + } + else if (*trackerInfo->pdwEffect & DROPEFFECT_LINK) + { + SetCursor(LoadCursorA(OLE32_hInstance, MAKEINTRESOURCE(3))); + } + else + { + SetCursor(LoadCursorA(OLE32_hInstance, MAKEINTRESOURCE(0))); + } + } +} + +/*** + * OLEDD_TrackStateChange() + * + * This method is invoked while a drag and drop operation is in effect. + * It is used to notify the drop target/drop source callbacks when + * the state of the keyboard or mouse button change. + * + * params: + * trackerInfo - Pointer to the structure identifying the + * drag & drop operation that is currently + * active. + * mousePos - Current position of the mouse in screen + * coordinates. + * keyState - Contains the state of the shift keys and the + * mouse buttons (MK_LBUTTON and the like) + */ +static void OLEDD_TrackStateChange( + TrackerWindowInfo* trackerInfo, + POINT mousePos, + DWORD keyState) +{ + /* + * Ask the drop source what to do with the operation. + */ + trackerInfo->returnValue = IDropSource_QueryContinueDrag( + trackerInfo->dropSource, + trackerInfo->escPressed, + keyState); + + /* + * All the return valued will stop the operation except the S_OK + * return value. + */ + if (trackerInfo->returnValue!=S_OK) + { + /* + * Make sure the message loop in DoDragDrop stops + */ + trackerInfo->trackingDone = TRUE; + + /* + * Release the mouse in case the drop target decides to show a popup + * or a menu or something. + */ + ReleaseCapture(); + + /* + * If we end-up over a target, drop the object in the target or + * inform the target that the operation was cancelled. + */ + if (trackerInfo->curDragTarget!=0) + { + switch (trackerInfo->returnValue) + { + /* + * If the source wants us to complete the operation, we tell + * the drop target that we just dropped the object in it. + */ + case DRAGDROP_S_DROP: + { + POINTL mousePosParam; + + /* + * The documentation tells me that the coordinate should be + * in the target window's coordinate space. However, the tests + * I made tell me the coordinates should be in screen coordinates. + */ + mousePosParam.x = mousePos.x; + mousePosParam.y = mousePos.y; + + IDropTarget_Drop(trackerInfo->curDragTarget, + trackerInfo->dataObject, + keyState, + mousePosParam, + trackerInfo->pdwEffect); + break; + } + /* + * If the source told us that we should cancel, fool the drop + * target by telling it that the mouse left it's window. + * Also set the drop effect to "NONE" in case the application + * ignores the result of DoDragDrop. + */ + case DRAGDROP_S_CANCEL: + IDropTarget_DragLeave(trackerInfo->curDragTarget); + *trackerInfo->pdwEffect = DROPEFFECT_NONE; + break; + } + } + } +} + +/*** + * OLEDD_GetButtonState() + * + * This method will use the current state of the keyboard to build + * a button state mask equivalent to the one passed in the + * WM_MOUSEMOVE wParam. + */ +static DWORD OLEDD_GetButtonState() +{ + BYTE keyboardState[256]; + DWORD keyMask = 0; + + GetKeyboardState(keyboardState); + + if ( (keyboardState[VK_SHIFT] & 0x80) !=0) + keyMask |= MK_SHIFT; + + if ( (keyboardState[VK_CONTROL] & 0x80) !=0) + keyMask |= MK_CONTROL; + + if ( (keyboardState[VK_LBUTTON] & 0x80) !=0) + keyMask |= MK_LBUTTON; + + if ( (keyboardState[VK_RBUTTON] & 0x80) !=0) + keyMask |= MK_RBUTTON; + + if ( (keyboardState[VK_MBUTTON] & 0x80) !=0) + keyMask |= MK_MBUTTON; + + return keyMask; +} + +/*** + * OLEDD_GetButtonState() + * + * This method will read the default value of the registry key in + * parameter and extract a DWORD value from it. The registry key value + * can be in a string key or a DWORD key. + * + * params: + * regKey - Key to read the default value from + * pdwValue - Pointer to the location where the DWORD + * value is returned. This value is not modified + * if the value is not found. + */ + +static void OLEUTL_ReadRegistryDWORDValue( + HKEY regKey, + DWORD* pdwValue) +{ + char buffer[20]; + DWORD dwKeyType; + DWORD cbData = 20; + LONG lres; + + lres = RegQueryValueExA(regKey, + "", + NULL, + &dwKeyType, + (LPBYTE)buffer, + &cbData); + + if (lres==ERROR_SUCCESS) + { + switch (dwKeyType) + { + case REG_DWORD: + *pdwValue = *(DWORD*)buffer; + break; + case REG_EXPAND_SZ: + case REG_MULTI_SZ: + case REG_SZ: + *pdwValue = (DWORD)strtoul(buffer, NULL, 10); + break; + } + } +} + +/****************************************************************************** + * OleMetaFilePictFromIconAndLabel + * + * Returns a global memory handle to a metafile which contains the icon and + * label given. + * I guess the result of that should look somehow like desktop icons. + * If no hIcon is given, we load the icon via lpszSourceFile and iIconIndex. + * This code might be wrong at some places. + */ +DWORD WINAPI OleMetaFilePictFromIconAndLabel16( + DWORD hIcon, + PVOID lpszLabel, + PVOID lpszSourceFile, + DWORD iIconIndex +) { + UNIMPLEMENTED; + return 0; +} + +/****************************************************************************** + * DllDebugObjectRPCHook + * turns on and off internal debugging, pointer is only used on macintosh + */ + +BOOL WINAPI DllDebugObjectRPCHook(BOOL b, void *dummy) +{ + Print(MIN_TRACE, ("stub\n")); + return TRUE; +} #endif - - diff --git a/reactos/lib/ole32/ole32.def b/reactos/lib/ole32/ole32.def index 34d7f37f9ab..9dd86d2fa4c 100644 --- a/reactos/lib/ole32/ole32.def +++ b/reactos/lib/ole32/ole32.def @@ -1,194 +1,307 @@ LIBRARY ole32.dll + EXPORTS -;BindMoniker @9 -;CLSIDFromProgID @14 -;CLSIDFromProgIDEx @15 -;CLSIDFromString @16 -;CoAddRefServerProcess @17 -;CoAllowSetForegroundWindow @18 - CoBuildVersion@0 -;CoCancelCall @20 -;CoCopyProxy @21 -;CoCreateFreeThreadedMarshaler @22 -;CoCreateGuid @23 - CoCreateInstance@20 -;CoCreateInstanceEx @25 -;CoDisableCallCancellation @28 -;CoDisconnectObject @29 -;CoDosDateTimeToFileTime @30 -;CoEnableCallCancellation @31 -;CoFileTimeNow @32 -;CoFileTimeToDosDateTime @33 - CoFreeAllLibraries@0 -;CoFreeLibrary @35 -;CoFreeUnusedLibraries @36 -;CoGetCallContext @38 -;CoGetCancelObject @40 - CoGetClassObject@20 -;CoGetCurrentProcess @44 -;CoGetInstanceFromFile @45 -;CoGetInstanceFromIStorage @46 -;CoGetInterfaceAndReleaseStream @47 -;CoGetMalloc @48 -;CoGetMarshalSizeMax @49 -;CoGetObject @50 -;CoGetObjectContext @51 -;CoGetPSClsid @52 -;CoGetStandardMarshal @53 -;CoGetStdMarshalEx @55 -;CoGetTreatAsClass @56 -;CoImpersonateClient @57 - CoInitialize@4 - CoInitializeEx@8 -;CoInitializeSecurity @60 -;CoInstall @62 -;CoIsHandlerConnected @63 -;CoIsOle1Class @64 -;CoLoadLibrary @65 -;CoLockObjectExternal @66 -;CoMarshalHresult @67 -;CoMarshalInterThreadInterfaceInStream @68 -;CoMarshalInterface @69 -;CoQueryAuthenticationServices @70 -;CoQueryClientBlanket @71 -;CoQueryProxyBlanket @72 -;CoRegisterChannelHook @75 -;CoRegisterClassObject @76 -;CoRegisterMallocSpy @77 -;CoRegisterMessageFilter @78 -;CoRegisterPSClsid @79 -;CoRegisterSurrogate @80 -;CoReleaseMarshalData @82 -;CoReleaseServerProcess @83 -;CoResumeClassObjects @84 -;CoRevertToSelf @85 -;CoRevokeClassObject @86 -;CoRevokeMallocSpy @87 -;CoSetCancelObject @88 -;CoSetProxyBlanket @89 -;CoSuspendClassObjects @91 -;CoSwitchCallContext @92 -;CoTaskMemAlloc @93 -;CoTaskMemFree @94 -;CoTaskMemRealloc @95 -;CoTestCancel @96 -;CoTreatAsClass @97 - CoUninitialize@0 -;CoUnmarshalHresult @100 -;CoUnmarshalInterface @101 -;CoWaitForMultipleHandles @102 -;CreateAntiMoniker @103 -;CreateBindCtx @104 -;CreateClassMoniker @105 -;CreateDataAdviseHolder @106 -;CreateDataCache @107 -;CreateErrorInfo @108 -;CreateFileMoniker @109 -;CreateGenericComposite @110 -;CreateILockBytesOnHGlobal @111 -;CreateItemMoniker @112 -;CreateObjrefMoniker @113 -;CreateOleAdviseHolder @114 -;CreatePointerMoniker @115 -;CreateStreamOnHGlobal @117 -;DllGetClassObject @120 PRIVATE -;DllRegisterServer @122 PRIVATE -;DoDragDrop @123 -;FmtIdToPropStgName @125 -;FreePropVariantArray @126 -;GetClassFile @127 -;GetConvertStg @128 -;GetErrorInfo @130 -;GetHGlobalFromILockBytes @131 -;GetHGlobalFromStream @132 -;GetRunningObjectTable @134 -;IIDFromString @184 -;IsAccelerator @185 -;MkParseDisplayName @191 -;MonikerCommonPrefixWith @192 -;MonikerRelativePathTo @193 -;OleBuildVersion @194 -;OleConvertIStorageToOLESTREAM @195 -;OleConvertIStorageToOLESTREAMEx @196 -;OleConvertOLESTREAMToIStorage @197 -;OleConvertOLESTREAMToIStorageEx @198 -;OleCreate @199 -;OleCreateDefaultHandler @200 -;OleCreateEmbeddingHelper @201 -;OleCreateEx @202 -;OleCreateFromData @203 -;OleCreateFromDataEx @204 -;OleCreateFromFile @205 -;OleCreateFromFileEx @206 -;OleCreateLink @207 -;OleCreateLinkEx @208 -;OleCreateLinkFromData @209 -;OleCreateLinkFromDataEx @210 -;OleCreateLinkToFile @211 -;OleCreateLinkToFileEx @212 -;OleCreateMenuDescriptor @213 -;OleCreateStaticFromData @214 -;OleDestroyMenuDescriptor @215 -;OleDoAutoConvert @216 -;OleDraw @217 -;OleDuplicateData @218 -;OleFlushClipboard @219 -;OleGetAutoConvert @220 -;OleGetClipboard @221 -;OleGetIconOfClass @222 -;OleGetIconOfFile @223 -OleInitialize=OleInitialize@4 -;OleIsCurrentClipboard @226 -;OleIsRunning @227 -;OleLoad @228 -;OleLoadFromStream @229 -;OleLockRunning @230 -;OleMetafilePictFromIconAndLabel @231 -;OleNoteObjectVisible @232 -;OleQueryCreateFromData @233 -;OleQueryLinkFromData @234 -;OleRegEnumFormatEtc @235 -;OleRegEnumVerbs @236 -;OleRegGetMiscStatus @237 -;OleRegGetUserType @238 -;OleRun @239 -;OleSave @240 -;OleSaveToStream @241 -;OleSetAutoConvert @242 -;OleSetClipboard @243 -;OleSetContainedObject @244 -;OleSetMenuDescriptor @245 -;OleTranslateAccelerator @246 -OleUninitialize=OleUninitialize@0 -;ProgIDFromCLSID @249 -;PropStgNameToFmtId @250 -;PropVariantClear @253 -;PropVariantCopy @254 -;ReadClassStg @255 -;ReadClassStm @256 -;ReadFmtUserTypeStg @257 -;RegisterDragDrop @260 -;ReleaseStgMedium @261 -;RevokeDragDrop @262 -;SetConvertStg @271 -;StgCreateDocfile @274 -;StgCreateDocfileOnILockBytes @275 -;StgCreatePropSetStg @276 -;StgCreatePropStg @277 -;StgCreateStorageEx @278 -;StgGetIFillLockBytesOnFile @279 -;StgGetIFillLockBytesOnILockBytes @280 -;StgIsStorageFile @281 -;StgIsStorageILockBytes @282 -;StgOpenAsyncDocfileOnIFillLockBytes @283 -;StgOpenPropStg @284 -;StgOpenStorage @285 -;StgOpenStorageEx @286 -;StgOpenStorageOnILockBytes @288 -;StgSetTimes @289 -;StringFromCLSID @290 -;StringFromGUID2 @291 -;StringFromIID @292 -;WriteClassStg @298 -;WriteClassStm @299 -;WriteFmtUserTypeStg @300 +;BindMoniker @ 9 +;CLIPFORMAT_UserFree @ 10 +;CLIPFORMAT_UserMarshal @ 11 +;CLIPFORMAT_UserSize @ 12 +;CLIPFORMAT_UserUnmarshal @ 13 +CLSIDFromProgID@8 @ 14 +;CLSIDFromProgIDEx @ 15 +CLSIDFromString@8 @ 16 +CoAddRefServerProcess@0 @ 17 +CoAllowSetForegroundWindow@8 @ 18 +CoBuildVersion@0 @ 19 +CoCancelCall@8 @ 20 +CoCopyProxy@8 @ 21 +CoCreateFreeThreadedMarshaler@8 @ 22 +CoCreateGuid@4 @ 23 +CoCreateInstance@20 @ 24 +CoCreateInstanceEx@24 @ 25 +;CoCreateObjectInContext @ 26 +;CoDeactivateObject @ 27 +CoDisableCallCancellation@4 @ 28 +CoDisconnectObject@8 @ 29 +CoDosDateTimeToFileTime@12 @ 30 +CoEnableCallCancellation@4 @ 31 +CoFileTimeNow@4 @ 32 +CoFileTimeToDosDateTime@12 @ 33 +CoFreeAllLibraries@0 @ 34 +CoFreeLibrary@4 @ 35 +CoFreeUnusedLibraries@0 @ 36 +;CoGetApartmentID @ 37 +CoGetCallContext@8 @ 38 +;CoGetCallerTID @ 39 +CoGetCancelObject@12 @ 40 +CoGetClassObject@20 @ 41 +;CoGetClassVersion @ 42 +;CoGetCurrentLogicalThreadId @ 43 +CoGetCurrentProcess@0 @ 44 +CoGetInstanceFromFile@32 @ 45 +CoGetInstanceFromIStorage@28 @ 46 +CoGetInterfaceAndReleaseStream@12 @ 47 +CoGetMalloc@8 @ 48 +CoGetMarshalSizeMax@24 @ 49 +CoGetObject@16 @ 50 +CoGetObjectContext@8 @ 51 +CoGetPSClsid@8 @ 52 +CoGetStandardMarshal@24 @ 53 +;CoGetState @ 54 +CoGetStdMarshalEx@12 @ 55 +CoGetTreatAsClass@8 @ 56 +CoImpersonateClient@0 @ 57 +CoInitialize@4 @ 58 +CoInitializeEx@8 @ 59 +CoInitializeSecurity@36 @ 60 +CoInitializeWOW@8 @ 61 +;CoInstall @ 62 +CoIsHandlerConnected@4 @ 63 +;CoIsOle1Class @ 64 +CoLoadLibrary@8 @ 65 +CoLockObjectExternal@12 @ 66 +CoMarshalHresult@8 @ 67 +CoMarshalInterThreadInterfaceInStream@12 @ 68 +CoMarshalInterface@24 @ 69 +CoQueryAuthenticationServices@8 @ 70 +CoQueryClientBlanket@28 @ 71 +CoQueryProxyBlanket@32 @ 72 +;CoQueryReleaseObject @ 73 +;CoReactivateObject @ 74 +;CoRegisterChannelHook @ 75 +CoRegisterClassObject@20 @ 76 +CoRegisterMallocSpy@4 @ 77 +CoRegisterMessageFilter@8 @ 78 +CoRegisterPSClsid@8 @ 79 +;CoRegisterSurrogate @ 80 +;CoRegisterSurrogateEx @ 81 +CoReleaseMarshalData@4 @ 82 +CoReleaseServerProcess@0 @ 83 +CoResumeClassObjects@0 @ 84 +CoRevertToSelf@0 @ 85 +CoRevokeClassObject@4 @ 86 +CoRevokeMallocSpy@0 @ 87 +CoSetCancelObject@4 @ 88 +CoSetProxyBlanket@32 @ 89 +CoSetState@4 @ 90 +CoSuspendClassObjects@0 @ 91 +CoSwitchCallContext@8 @ 92 +CoTaskMemAlloc@4 @ 93 +CoTaskMemFree@4 @ 94 +CoTaskMemRealloc@8 @ 95 +CoTestCancel@0 @ 96 +CoTreatAsClass@8 @ 97 +CoUninitialize@0 @ 98 +;CoUnloadingWOW @ 99 +CoUnmarshalHresult@8 @ 100 +CoUnmarshalInterface@12 @ 101 +CoWaitForMultipleHandles@20 @ 102 +CreateAntiMoniker@4 @ 103 +CreateBindCtx@8 @ 104 +;CreateClassMoniker @ 105 +;CreateDataAdviseHolder @ 106 +CreateDataCache@16 @ 107 +;CreateErrorInfo @ 108 +CreateFileMoniker@8 @ 109 +CreateGenericComposite@12 @ 110 +CreateILockBytesOnHGlobal@12 @ 111 +CreateItemMoniker@12 @ 112 +;CreateObjrefMoniker @ 113 +;CreateOleAdviseHolder @ 114 +;CreatePointerMoniker @ 115 +;CreateStdProgressIndicator @ 116 +;CreateStreamOnHGlobal @ 117 +;DcomChannelSetHResult @ 118 +;DllDebugObjectRPCHook @ 119 +;DllGetClassObject @ 120 +;DllGetClassObjectWOW @ 121 +;DllRegisterServer @ 122 +;DoDragDrop @ 123 +;EnableHookObject @ 124 +;FmtIdToPropStgName @ 125 +;FreePropVariantArray @ 126 +GetClassFile@8 @ 127 +GetConvertStg@4 @ 128 +;GetDocumentBitStg @ 129 +;GetErrorInfo @ 130 +GetHGlobalFromILockBytes@8 @ 131 +;GetHGlobalFromStream @ 132 +;GetHookInterface @ 133 +GetRunningObjectTable@8 @ 134 +;HACCEL_UserFree @ 135 +;HACCEL_UserMarshal @ 136 +;HACCEL_UserSize @ 137 +;HACCEL_UserUnmarshal @ 138 +;HBITMAP_UserFree @ 139 +;HBITMAP_UserMarshal @ 140 +;HBITMAP_UserSize @ 141 +;HBITMAP_UserUnmarshal @ 142 +;HBRUSH_UserFree @ 143 +;HBRUSH_UserMarshal @ 144 +;HBRUSH_UserSize @ 145 +;HBRUSH_UserUnmarshal @ 146 +;HDC_UserFree @ 147 +;HDC_UserMarshal @ 148 +;HDC_UserSize @ 149 +;HDC_UserUnmarshal @ 150 +;HENHMETAFILE_UserFree @ 151 +;HENHMETAFILE_UserMarshal @ 152 +;HENHMETAFILE_UserSize @ 153 +;HENHMETAFILE_UserUnmarshal @ 154 +;HGLOBAL_UserFree @ 155 +;HGLOBAL_UserMarshal @ 156 +;HGLOBAL_UserSize @ 157 +;HGLOBAL_UserUnmarshal @ 158 +;HICON_UserFree @ 159 +;HICON_UserMarshal @ 160 +;HICON_UserSize @ 161 +;HICON_UserUnmarshal @ 162 +;HMENU_UserFree @ 163 +;HMENU_UserMarshal @ 164 +;HMENU_UserSize @ 165 +;HMENU_UserUnmarshal @ 166 +;HMETAFILEPICT_UserFree @ 167 +;HMETAFILEPICT_UserMarshal @ 168 +;HMETAFILEPICT_UserSize @ 169 +;HMETAFILEPICT_UserUnmarshal @ 170 +;HMETAFILE_UserFree @ 171 +;HMETAFILE_UserMarshal @ 172 +;HMETAFILE_UserSize @ 173 +;HMETAFILE_UserUnmarshal @ 174 +;HPALETTE_UserFree @ 175 +;HPALETTE_UserMarshal @ 176 +;HPALETTE_UserSize @ 177 +;HPALETTE_UserUnmarshal @ 178 +;HWND_UserFree @ 179 +;HWND_UserMarshal @ 180 +;HWND_UserSize @ 181 +;HWND_UserUnmarshal @ 182 +;HkOleRegisterObject @ 183 +;IIDFromString @ 184 +;IsAccelerator @ 185 +IsEqualGUID@8 @ 186 +;IsValidIid @ 187 +IsValidInterface@4 @ 188 +;IsValidPtrIn @ 189 +;IsValidPtrOut @ 190 +MkParseDisplayName@16 @ 191 +MonikerCommonPrefixWith@12 @ 192 +;MonikerRelativePathTo @ 193 +;OleBuildVersion @ 194 +OleConvertIStorageToOLESTREAM@8 @ 195 +;OleConvertIStorageToOLESTREAMEx @ 196 +OleConvertOLESTREAMToIStorage@12 @ 197 +;OleConvertOLESTREAMToIStorageEx @ 198 +;OleCreate @ 199 +;OleCreateDefaultHandler @ 200 +;OleCreateEmbeddingHelper @ 201 +;OleCreateEx @ 202 +;OleCreateFromData @ 203 +;OleCreateFromDataEx @ 204 +;OleCreateFromFile @ 205 +;OleCreateFromFileEx @ 206 +;OleCreateLink @ 207 +;OleCreateLinkEx @ 208 +;OleCreateLinkFromData @ 209 +;OleCreateLinkFromDataEx @ 210 +;OleCreateLinkToFile @211 +;OleCreateLinkToFileEx @ 212 +;OleCreateMenuDescriptor @ 213 +;OleCreateStaticFromData @ 214 +;OleDestroyMenuDescriptor @215 +;OleDoAutoConvert @ 216 +;OleDraw @ 217 +;OleDuplicateData @ 218 +;OleFlushClipboard @ 219 +OleGetAutoConvert@8 @ 220 +;OleGetClipboard @ 221 +;OleGetIconOfClass @ 222 +;OleGetIconOfFile @ 223 +;OleInitialize @ 224 +;OleInitializeWOW @ 225 +;OleIsCurrentClipboard @ 226 +;OleIsRunning @ 227 +;OleLoad @ 228 +OleLoadFromStream@12 @ 229 +;OleLockRunning @ 230 +;OleMetafilePictFromIconAndLabel @ 231 +;OleNoteObjectVisible @ 232 +;OleQueryCreateFromData @ 233 +;OleQueryLinkFromData @ 234 +;OleRegEnumFormatEtc @ 235 +;OleRegEnumVerbs @ 236 +;OleRegGetMiscStatus @ 237 +;OleRegGetUserType @ 238 +OleRun@4 @ 239 +;OleSave @ 240 +OleSaveToStream@8 @ 241 +OleSetAutoConvert@8 @ 242 +;OleSetClipboard @ 243 +;OleSetContainedObject @ 244 +;OleSetMenuDescriptor @ 245 +;OleTranslateAccelerator @ 246 +;OleUninitialize @ 247 +;OpenOrCreateStream @ 248 +ProgIDFromCLSID@8 @ 249 +;PropStgNameToFmtId @ 250 +;PropSysAllocString @ 251 +;PropSysFreeString @ 252 +;PropVariantChangeType @ 1 +;PropVariantClear @ 253 +;PropVariantCopy @ 254 +ReadClassStg@8 @ 255 +ReadClassStm@8 @ 256 +;ReadFmtUserTypeStg @ 257 +;ReadOleStg @ 258 +;ReadStringStream @ 259 +;RegisterDragDrop @ 260 +;ReleaseStgMedium @ 261 +;RevokeDragDrop @ 262 +;SNB_UserFree @ 263 +;SNB_UserMarshal @ 264 +;SNB_UserSize @ 265 +;SNB_UserUnmarshal @ 266 +;STGMEDIUM_UserFree @ 267 +;STGMEDIUM_UserMarshal @ 268 +;STGMEDIUM_UserSize @ 269 +;STGMEDIUM_UserUnmarshal @ 270 +;SetConvertStg @ 271 +;SetDocumentBitStg @ 272 +;SetErrorInfo @ 273 +;StgConvertPropertyToVariant @ 2 +;StgConvertVariantToProperty @ 3 +StgCreateDocfile@16 @ 274 +StgCreateDocfileOnILockBytes@16 @ 275 +;StgCreatePropSetStg @ 276 +;StgCreatePropStg @ 277 +;StgCreateStorageEx @ 278 +;StgGetIFillLockBytesOnFile @ 279 +;StgGetIFillLockBytesOnILockBytes @ 280 +StgIsStorageFile@4 @ 281 +StgIsStorageILockBytes@4 @ 282 +;StgOpenAsyncDocfileOnIFillLockBytes @ 283 +;StgOpenPropStg @ 284 +StgOpenStorage@24 @ 285 +;StgOpenStorageEx @ 286 +;StgOpenStorageOnHandle @ 287 +StgOpenStorageOnILockBytes@24 @ 288 +;StgPropertyLengthAsVariant @ 4 +StgSetTimes@16 @ 289 +StringFromCLSID@8 @ 290 +StringFromGUID2@12 @ 291 +;StringFromIID @ 292 +;UpdateDCOMSettings @ 293 +;UtConvertDvtd16toDvtd32 @ 294 +;UtConvertDvtd32toDvtd16 @ 295 +;UtGetDvtd16Info @ 296 +;UtGetDvtd32Info @ 297 +;WdtpInterfacePointer_UserFree @ 5 +;WdtpInterfacePointer_UserMarshal @ 6 +;WdtpInterfacePointer_UserSize @ 7 +;WdtpInterfacePointer_UserUnmarshal @ 8 +WriteClassStg@8 @ 298 +WriteClassStm@8 @ 299 +;WriteFmtUserTypeStg @ 300 +;WriteOleStg @ 301 +;WriteStringStream @ 302 + +; EOF diff --git a/reactos/lib/ole32/ole32.edf b/reactos/lib/ole32/ole32.edf deleted file mode 100644 index 95beb9d918f..00000000000 --- a/reactos/lib/ole32/ole32.edf +++ /dev/null @@ -1,194 +0,0 @@ -LIBRARY ole32.dll -EXPORTS -;BindMoniker @9 -;CLSIDFromProgID @14 -;CLSIDFromProgIDEx @15 -;CLSIDFromString @16 -;CoAddRefServerProcess @17 -;CoAllowSetForegroundWindow @18 - CoBuildVersion=CoBuildVersion@0 -;CoCancelCall @20 -;CoCopyProxy @21 -;CoCreateFreeThreadedMarshaler @22 -;CoCreateGuid @23 - CoCreateInstance=CoCreateInstance@20 -;CoCreateInstanceEx @25 -;CoDisableCallCancellation @28 -;CoDisconnectObject @29 -;CoDosDateTimeToFileTime @30 -;CoEnableCallCancellation @31 -;CoFileTimeNow @32 -;CoFileTimeToDosDateTime @33 - CoFreeAllLibraries=CoFreeAllLibraries@0 -;CoFreeLibrary @35 -;CoFreeUnusedLibraries @36 -;CoGetCallContext @38 -;CoGetCancelObject @40 - CoGetClassObject=CoGetClassObject@20 -;CoGetCurrentProcess @44 -;CoGetInstanceFromFile @45 -;CoGetInstanceFromIStorage @46 -;CoGetInterfaceAndReleaseStream @47 -;CoGetMalloc @48 -;CoGetMarshalSizeMax @49 -;CoGetObject @50 -;CoGetObjectContext @51 -;CoGetPSClsid @52 -;CoGetStandardMarshal @53 -;CoGetStdMarshalEx @55 -;CoGetTreatAsClass @56 -;CoImpersonateClient @57 - CoInitialize=CoInitialize@4 - CoInitializeEx=CoInitializeEx@8 -;CoInitializeSecurity @60 -;CoInstall @62 -;CoIsHandlerConnected @63 -;CoIsOle1Class @64 -;CoLoadLibrary @65 -;CoLockObjectExternal @66 -;CoMarshalHresult @67 -;CoMarshalInterThreadInterfaceInStream @68 -;CoMarshalInterface @69 -;CoQueryAuthenticationServices @70 -;CoQueryClientBlanket @71 -;CoQueryProxyBlanket @72 -;CoRegisterChannelHook @75 -;CoRegisterClassObject @76 -;CoRegisterMallocSpy @77 -;CoRegisterMessageFilter @78 -;CoRegisterPSClsid @79 -;CoRegisterSurrogate @80 -;CoReleaseMarshalData @82 -;CoReleaseServerProcess @83 -;CoResumeClassObjects @84 -;CoRevertToSelf @85 -;CoRevokeClassObject @86 -;CoRevokeMallocSpy @87 -;CoSetCancelObject @88 -;CoSetProxyBlanket @89 -;CoSuspendClassObjects @91 -;CoSwitchCallContext @92 -;CoTaskMemAlloc @93 -;CoTaskMemFree @94 -;CoTaskMemRealloc @95 -;CoTestCancel @96 -;CoTreatAsClass @97 - CoUninitialize=CoUninitialize@0 -;CoUnmarshalHresult @100 -;CoUnmarshalInterface @101 -;CoWaitForMultipleHandles @102 -;CreateAntiMoniker @103 -;CreateBindCtx @104 -;CreateClassMoniker @105 -;CreateDataAdviseHolder @106 -;CreateDataCache @107 -;CreateErrorInfo @108 -;CreateFileMoniker @109 -;CreateGenericComposite @110 -;CreateILockBytesOnHGlobal @111 -;CreateItemMoniker @112 -;CreateObjrefMoniker @113 -;CreateOleAdviseHolder @114 -;CreatePointerMoniker @115 -;CreateStreamOnHGlobal @117 -;DllGetClassObject @120 PRIVATE -;DllRegisterServer @122 PRIVATE -;DoDragDrop @123 -;FmtIdToPropStgName @125 -;FreePropVariantArray @126 -;GetClassFile @127 -;GetConvertStg @128 -;GetErrorInfo @130 -;GetHGlobalFromILockBytes @131 -;GetHGlobalFromStream @132 -;GetRunningObjectTable @134 -;IIDFromString @184 -;IsAccelerator @185 -;MkParseDisplayName @191 -;MonikerCommonPrefixWith @192 -;MonikerRelativePathTo @193 -;OleBuildVersion @194 -;OleConvertIStorageToOLESTREAM @195 -;OleConvertIStorageToOLESTREAMEx @196 -;OleConvertOLESTREAMToIStorage @197 -;OleConvertOLESTREAMToIStorageEx @198 -;OleCreate @199 -;OleCreateDefaultHandler @200 -;OleCreateEmbeddingHelper @201 -;OleCreateEx @202 -;OleCreateFromData @203 -;OleCreateFromDataEx @204 -;OleCreateFromFile @205 -;OleCreateFromFileEx @206 -;OleCreateLink @207 -;OleCreateLinkEx @208 -;OleCreateLinkFromData @209 -;OleCreateLinkFromDataEx @210 -;OleCreateLinkToFile @211 -;OleCreateLinkToFileEx @212 -;OleCreateMenuDescriptor @213 -;OleCreateStaticFromData @214 -;OleDestroyMenuDescriptor @215 -;OleDoAutoConvert @216 -;OleDraw @217 -;OleDuplicateData @218 -;OleFlushClipboard @219 -;OleGetAutoConvert @220 -;OleGetClipboard @221 -;OleGetIconOfClass @222 -;OleGetIconOfFile @223 -;OleInitialize @224 -;OleIsCurrentClipboard @226 -;OleIsRunning @227 -;OleLoad @228 -;OleLoadFromStream @229 -;OleLockRunning @230 -;OleMetafilePictFromIconAndLabel @231 -;OleNoteObjectVisible @232 -;OleQueryCreateFromData @233 -;OleQueryLinkFromData @234 -;OleRegEnumFormatEtc @235 -;OleRegEnumVerbs @236 -;OleRegGetMiscStatus @237 -;OleRegGetUserType @238 -;OleRun @239 -;OleSave @240 -;OleSaveToStream @241 -;OleSetAutoConvert @242 -;OleSetClipboard @243 -;OleSetContainedObject @244 -;OleSetMenuDescriptor @245 -;OleTranslateAccelerator @246 -;OleUninitialize @247 -;ProgIDFromCLSID @249 -;PropStgNameToFmtId @250 -;PropVariantClear @253 -;PropVariantCopy @254 -;ReadClassStg @255 -;ReadClassStm @256 -;ReadFmtUserTypeStg @257 -;RegisterDragDrop @260 -;ReleaseStgMedium @261 -;RevokeDragDrop @262 -;SetConvertStg @271 -;StgCreateDocfile @274 -;StgCreateDocfileOnILockBytes @275 -;StgCreatePropSetStg @276 -;StgCreatePropStg @277 -;StgCreateStorageEx @278 -;StgGetIFillLockBytesOnFile @279 -;StgGetIFillLockBytesOnILockBytes @280 -;StgIsStorageFile @281 -;StgIsStorageILockBytes @282 -;StgOpenAsyncDocfileOnIFillLockBytes @283 -;StgOpenPropStg @284 -;StgOpenStorage @285 -;StgOpenStorageEx @286 -;StgOpenStorageOnILockBytes @288 -;StgSetTimes @289 -;StringFromCLSID @290 -;StringFromGUID2 @291 -;StringFromIID @292 -;WriteClassStg @298 -;WriteClassStm @299 -;WriteFmtUserTypeStg @300 \ No newline at end of file diff --git a/reactos/lib/ole32/rpcrt4_main.c b/reactos/lib/ole32/rpcrt4_main.c new file mode 100644 index 00000000000..f826c383af7 --- /dev/null +++ b/reactos/lib/ole32/rpcrt4_main.c @@ -0,0 +1,306 @@ +/* + * RPCRT4 + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/*********************************************************************** + * RPCRT4_LibMain + * + * PARAMS + * hinstDLL [I] handle to the DLL's instance + * fdwReason [I] + * lpvReserved [I] reserved, must be NULL + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ + +BOOL WINAPI +RPCRT4_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + +/************************************************************************* + * UuidCreate [RPCRT4] + * + * Creates a 128bit UUID. + * Implemented according the DCE specification for UUID generation. + * Code is based upon uuid library in e2fsprogs by Theodore Ts'o. + * Copyright (C) 1996, 1997 Theodore Ts'o. + * + * RETURNS + * + * S_OK if successful. + */ +RPC_STATUS WINAPI UuidCreate(UUID *Uuid) +{ +#if 1 + UNIMPLEMENTED; + return S_OK; +#else + static char has_init = 0; + unsigned char a[6]; + static int adjustment = 0; + static struct timeval last = {0, 0}; + static UINT16 clock_seq; + struct timeval tv; + unsigned long long clock_reg; + UINT clock_high, clock_low; + UINT16 temp_clock_seq, temp_clock_mid, temp_clock_hi_and_version; +#ifdef HAVE_NET_IF_H + int sd; + struct ifreq ifr, *ifrp; + struct ifconf ifc; + char buf[1024]; + int n, i; +#endif + + /* Have we already tried to get the MAC address? */ + if (!has_init) { +#ifdef HAVE_NET_IF_H + /* BSD 4.4 defines the size of an ifreq to be + * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len + * However, under earlier systems, sa_len isn't present, so + * the size is just sizeof(struct ifreq) + */ +#ifdef HAVE_SA_LEN +# ifndef max +# define max(a,b) ((a) > (b) ? (a) : (b)) +# endif +# define ifreq_size(i) max(sizeof(struct ifreq),\ +sizeof((i).ifr_name)+(i).ifr_addr.sa_len) +# else +# define ifreq_size(i) sizeof(struct ifreq) +# endif /* HAVE_SA_LEN */ + + sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if (sd < 0) { + /* if we can't open a socket, just use random numbers */ + /* set the multicast bit to prevent conflicts with real cards */ + a[0] = (rand() & 0xff) | 0x80; + a[1] = rand() & 0xff; + a[2] = rand() & 0xff; + a[3] = rand() & 0xff; + a[4] = rand() & 0xff; + a[5] = rand() & 0xff; + } else { + memset(buf, 0, sizeof(buf)); + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + /* get the ifconf interface */ + if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) { + close(sd); + /* no ifconf, so just use random numbers */ + /* set the multicast bit to prevent conflicts with real cards */ + a[0] = (rand() & 0xff) | 0x80; + a[1] = rand() & 0xff; + a[2] = rand() & 0xff; + a[3] = rand() & 0xff; + a[4] = rand() & 0xff; + a[5] = rand() & 0xff; + } else { + /* loop through the interfaces, looking for a valid one */ + n = ifc.ifc_len; + for (i = 0; i < n; i+= ifreq_size(*ifr) ) { + ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i); + strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ); + /* try to get the address for this interface */ +# ifdef SIOCGIFHWADDR + if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) + continue; + memcpy(a, (unsigned char *)&ifr.ifr_hwaddr.sa_data, 6); +# else +# ifdef SIOCGENADDR + if (ioctl(sd, SIOCGENADDR, &ifr) < 0) + continue; + memcpy(a, (unsigned char *) ifr.ifr_enaddr, 6); +# else + /* XXX we don't have a way of getting the hardware address */ + close(sd); + a[0] = 0; + break; +# endif /* SIOCGENADDR */ +# endif /* SIOCGIFHWADDR */ + /* make sure it's not blank */ + if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) + continue; + + goto valid_address; + } + /* if we didn't find a valid address, make a random one */ + /* once again, set multicast bit to avoid conflicts */ + a[0] = (rand() & 0xff) | 0x80; + a[1] = rand() & 0xff; + a[2] = rand() & 0xff; + a[3] = rand() & 0xff; + a[4] = rand() & 0xff; + a[5] = rand() & 0xff; + + valid_address: + close(sd); + } + } +#else + /* no networking info, so generate a random address */ + a[0] = (rand() & 0xff) | 0x80; + a[1] = rand() & 0xff; + a[2] = rand() & 0xff; + a[3] = rand() & 0xff; + a[4] = rand() & 0xff; + a[5] = rand() & 0xff; +#endif /* HAVE_NET_IF_H */ + has_init = 1; + } + + /* generate time element of GUID */ + + /* Assume that the gettimeofday() has microsecond granularity */ +#define MAX_ADJUSTMENT 10 + + try_again: + gettimeofday(&tv, 0); + if ((last.tv_sec == 0) && (last.tv_usec == 0)) { + clock_seq = ((rand() & 0xff) << 8) + (rand() & 0xff); + clock_seq &= 0x1FFF; + last = tv; + last.tv_sec--; + } + if ((tv.tv_sec < last.tv_sec) || + ((tv.tv_sec == last.tv_sec) && + (tv.tv_usec < last.tv_usec))) { + clock_seq = (clock_seq+1) & 0x1FFF; + adjustment = 0; + } else if ((tv.tv_sec == last.tv_sec) && + (tv.tv_usec == last.tv_usec)) { + if (adjustment >= MAX_ADJUSTMENT) + goto try_again; + adjustment++; + } else + adjustment = 0; + + clock_reg = tv.tv_usec*10 + adjustment; + clock_reg += ((unsigned long long) tv.tv_sec)*10000000; + clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000; + + clock_high = clock_reg >> 32; + clock_low = clock_reg; + temp_clock_seq = clock_seq | 0x8000; + temp_clock_mid = (UINT16)clock_high; + temp_clock_hi_and_version = (clock_high >> 16) | 0x1000; + + /* pack the information into the GUID structure */ + + ((unsigned char*)&Uuid->Data1)[3] = (unsigned char)clock_low; + clock_low >>= 8; + ((unsigned char*)&Uuid->Data1)[2] = (unsigned char)clock_low; + clock_low >>= 8; + ((unsigned char*)&Uuid->Data1)[1] = (unsigned char)clock_low; + clock_low >>= 8; + ((unsigned char*)&Uuid->Data1)[0] = (unsigned char)clock_low; + + ((unsigned char*)&Uuid->Data2)[1] = (unsigned char)temp_clock_mid; + temp_clock_mid >>= 8; + ((unsigned char*)&Uuid->Data2)[0] = (unsigned char)temp_clock_mid; + + ((unsigned char*)&Uuid->Data3)[1] = (unsigned char)temp_clock_hi_and_version; + temp_clock_hi_and_version >>= 8; + ((unsigned char*)&Uuid->Data3)[0] = (unsigned char)temp_clock_hi_and_version; + + ((unsigned char*)Uuid->Data4)[1] = (unsigned char)temp_clock_seq; + temp_clock_seq >>= 8; + ((unsigned char*)Uuid->Data4)[0] = (unsigned char)temp_clock_seq; + + ((unsigned char*)Uuid->Data4)[2] = a[0]; + ((unsigned char*)Uuid->Data4)[3] = a[1]; + ((unsigned char*)Uuid->Data4)[4] = a[2]; + ((unsigned char*)Uuid->Data4)[5] = a[3]; + ((unsigned char*)Uuid->Data4)[6] = a[4]; + ((unsigned char*)Uuid->Data4)[7] = a[5]; + + Print(MAX_TRACE, ("%s\n", PRINT_GUID(Uuid))); + + return S_OK; +#endif +} + +/************************************************************************* + * RpcStringFreeA [RPCRT4.436] + * + * Frees a character string allocated by the RPC run-time library. + * + * RETURNS + * + * S_OK if successful. + */ +RPC_STATUS WINAPI RpcStringFreeA(unsigned char** String) +{ + HeapFree( GetProcessHeap(), 0, *String); + + return S_OK; +} + +/************************************************************************* + * UuidToStringA [RPCRT4.450] + * + * Converts a UUID to a string. + * + * UUID format is 8 hex digits, followed by a hyphen then three groups of + * 4 hex digits each followed by a hyphen and then 12 hex digits + * + * RETURNS + * + * S_OK if successful. + * S_OUT_OF_MEMORY if unsucessful. + */ +RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, unsigned char** StringUuid) +{ + *StringUuid = HeapAlloc( GetProcessHeap(), 0, sizeof(char) * 37); + + + /* FIXME: this should be RPC_S_OUT_OF_MEMORY */ + if(!(*StringUuid)) + return ERROR_OUTOFMEMORY; + + sprintf(*StringUuid, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + Uuid->Data1, Uuid->Data2, Uuid->Data3, + Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], + Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], + Uuid->Data4[6], Uuid->Data4[7] ); + + return S_OK; /*FIXME: this should be RPC_S_OK */ +} + +/*********************************************************************** + * NdrDllRegisterProxy (RPCRT4.@) + */ +HRESULT WINAPI NdrDllRegisterProxy( + HMODULE hDll, /* [in] */ + void **pProxyFileList, /* [???] FIXME: const ProxyFileInfo ** */ + const CLSID *pclsid /* [in] */ +) { + Print(MIN_TRACE, ("(%x,%p,%s), stub!\n",hDll,pProxyFileList,PRINT_GUID(pclsid))); + return S_OK; +} diff --git a/reactos/lib/ole32/stg_bigblockfile.c b/reactos/lib/ole32/stg_bigblockfile.c new file mode 100644 index 00000000000..68dc3b90d54 --- /dev/null +++ b/reactos/lib/ole32/stg_bigblockfile.c @@ -0,0 +1,837 @@ +/****************************************************************************** + * + * BigBlockFile + * + * This is the implementation of a file that consists of blocks of + * a predetermined size. + * This class is used in the Compound File implementation of the + * IStorage and IStream interfaces. It provides the functionality + * to read and write any blocks in the file as well as setting and + * obtaining the size of the file. + * The blocks are indexed sequentially from the start of the file + * starting with -1. + * + * TODO: + * - Support for a transacted mode + * + * Copyright 1999 Thuy Nguyen + * + */ + +#include +#include +#include +#include + +#include +#include +#include "storage32.h" + +#include + +/*********************************************************** + * Data structures used internally by the BigBlockFile + * class. + */ + +/* We map in PAGE_SIZE-sized chunks. Must be a multiple of 4096. */ +#define PAGE_SIZE 131072 + +#define BLOCKS_PER_PAGE (PAGE_SIZE / BIG_BLOCK_SIZE) + +/* We keep a list of recently-discarded pages. This controls the + * size of that list. */ +#define MAX_VICTIM_PAGES 16 + +/* This structure provides one bit for each block in a page. + * Use BIGBLOCKFILE_{Test,Set,Clear}Bit to manipulate it. */ +typedef struct +{ + unsigned int bits[BLOCKS_PER_PAGE / (CHAR_BIT * sizeof(unsigned int))]; +} BlockBits; + +/*** + * This structure identifies the paged that are mapped + * from the file and their position in memory. It is + * also used to hold a reference count to those pages. + * + * page_index identifies which PAGE_SIZE chunk from the + * file this mapping represents. (The mappings are always + * PAGE_SIZE-aligned.) + */ +struct MappedPage +{ + MappedPage *next; + MappedPage *prev; + + DWORD page_index; + LPVOID lpBytes; + LONG refcnt; + + BlockBits readable_blocks; + BlockBits writable_blocks; +}; + +/*********************************************************** + * Prototypes for private methods + */ +static void* BIGBLOCKFILE_GetMappedView(LPBIGBLOCKFILE This, + DWORD page_index); +static void BIGBLOCKFILE_ReleaseMappedPage(LPBIGBLOCKFILE This, + MappedPage *page); +static void BIGBLOCKFILE_FreeAllMappedPages(LPBIGBLOCKFILE This); +static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This); +static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This); +static void* BIGBLOCKFILE_GetBigBlockPointer(LPBIGBLOCKFILE This, + ULONG index, + DWORD desired_access); +static MappedPage* BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This, + void* pBlock); +static MappedPage* BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This, + ULONG page_index); +static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags); +static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile); +static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt); + +/* Note that this evaluates a and b multiple times, so don't + * pass expressions with side effects. */ +#define ROUNDUP(a, b) ((((a) + (b) - 1)/(b))*(b)) + +/*********************************************************** + * Blockbits functions. + */ +static inline BOOL BIGBLOCKFILE_TestBit(const BlockBits *bb, + unsigned int index) +{ + unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int)); + unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int)); + + return bb->bits[array_index] & (1 << bit_index); +} + +static inline void BIGBLOCKFILE_SetBit(BlockBits *bb, unsigned int index) +{ + unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int)); + unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int)); + + bb->bits[array_index] |= (1 << bit_index); +} + +static inline void BIGBLOCKFILE_ClearBit(BlockBits *bb, unsigned int index) +{ + unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int)); + unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int)); + + bb->bits[array_index] &= ~(1 << bit_index); +} + +static inline void BIGBLOCKFILE_Zero(BlockBits *bb) +{ + memset(bb->bits, 0, sizeof(bb->bits)); +} + +/****************************************************************************** + * BIGBLOCKFILE_Construct + * + * Construct a big block file. Create the file mapping object. + * Create the read only mapped pages list, the writable mapped page list + * and the blocks in use list. + */ +BigBlockFile * BIGBLOCKFILE_Construct( + HANDLE hFile, + ILockBytes* pLkByt, + DWORD openFlags, + ULONG blocksize, + BOOL fileBased) +{ + LPBIGBLOCKFILE This; + + This = (LPBIGBLOCKFILE)HeapAlloc(GetProcessHeap(), 0, sizeof(BigBlockFile)); + + if (This == NULL) + return NULL; + + This->fileBased = fileBased; + + This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags); + + This->blocksize = blocksize; + + This->maplist = NULL; + This->victimhead = NULL; + This->victimtail = NULL; + This->num_victim_pages = 0; + + if (This->fileBased) + { + if (!BIGBLOCKFILE_FileInit(This, hFile)) + { + HeapFree(GetProcessHeap(), 0, This); + return NULL; + } + } + else + { + if (!BIGBLOCKFILE_MemInit(This, pLkByt)) + { + HeapFree(GetProcessHeap(), 0, This); + return NULL; + } + } + + return This; +} + +/****************************************************************************** + * BIGBLOCKFILE_FileInit + * + * Initialize a big block object supported by a file. + */ +static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile) +{ + This->pLkbyt = NULL; + This->hbytearray = 0; + This->pbytearray = NULL; + + This->hfile = hFile; + + if (This->hfile == INVALID_HANDLE_VALUE) + return FALSE; + + /* create the file mapping object + */ + This->hfilemap = CreateFileMappingA(This->hfile, + NULL, + This->flProtect, + 0, 0, + NULL); + + if (!This->hfilemap) + { + CloseHandle(This->hfile); + return FALSE; + } + + This->filesize.u.LowPart = GetFileSize(This->hfile, + &This->filesize.u.HighPart); + + This->maplist = NULL; + + Print(MAX_TRACE, ("file len %lu\n", This->filesize.u.LowPart)); + + return TRUE; +} + +/****************************************************************************** + * BIGBLOCKFILE_MemInit + * + * Initialize a big block object supported by an ILockBytes on HGLOABL. + */ +static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt) +{ + This->hfile = 0; + This->hfilemap = 0; + + /* + * Retrieve the handle to the byte array from the LockByte object. + */ + if (GetHGlobalFromILockBytes(plkbyt, &(This->hbytearray)) != S_OK) + { + Print(MIN_TRACE, ("May not be an ILockBytes on HGLOBAL\n")); + return FALSE; + } + + This->pLkbyt = plkbyt; + + /* + * Increment the reference count of the ILockByte object since + * we're keeping a reference to it. + */ + ILockBytes_AddRef(This->pLkbyt); + + This->filesize.u.LowPart = GlobalSize(This->hbytearray); + This->filesize.u.HighPart = 0; + + This->pbytearray = GlobalLock(This->hbytearray); + + Print(MAX_TRACE, ("mem on %p len %lu\n", This->pbytearray, This->filesize.u.LowPart)); + + return TRUE; +} + +/****************************************************************************** + * BIGBLOCKFILE_Destructor + * + * Destructor. Clean up, free memory. + */ +void BIGBLOCKFILE_Destructor( + LPBIGBLOCKFILE This) +{ + BIGBLOCKFILE_FreeAllMappedPages(This); + + if (This->fileBased) + { + CloseHandle(This->hfilemap); + CloseHandle(This->hfile); + } + else + { + GlobalUnlock(This->hbytearray); + ILockBytes_Release(This->pLkbyt); + } + + /* destroy this + */ + HeapFree(GetProcessHeap(), 0, This); +} + +/****************************************************************************** + * BIGBLOCKFILE_GetROBigBlock + * + * Returns the specified block in read only mode. + * Will return NULL if the block doesn't exists. + */ +void* BIGBLOCKFILE_GetROBigBlock( + LPBIGBLOCKFILE This, + ULONG index) +{ + /* + * block index starts at -1 + * translate to zero based index + */ + if (index == 0xffffffff) + index = 0; + else + index++; + + /* + * validate the block index + * + */ + if (This->blocksize * (index + 1) + > ROUNDUP(This->filesize.u.LowPart, This->blocksize)) + { + Print(MAX_TRACE, ("out of range %lu vs %lu\n", This->blocksize * (index + 1), + This->filesize.u.LowPart)); + return NULL; + } + + return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_READ); +} + +/****************************************************************************** + * BIGBLOCKFILE_GetBigBlock + * + * Returns the specified block. + * Will grow the file if necessary. + */ +void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index) +{ + /* + * block index starts at -1 + * translate to zero based index + */ + if (index == 0xffffffff) + index = 0; + else + index++; + + /* + * make sure that the block physically exists + */ + if ((This->blocksize * (index + 1)) > This->filesize.u.LowPart) + { + ULARGE_INTEGER newSize; + + newSize.u.HighPart = 0; + newSize.u.LowPart = This->blocksize * (index + 1); + + BIGBLOCKFILE_SetSize(This, newSize); + } + + return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_WRITE); +} + +/****************************************************************************** + * BIGBLOCKFILE_ReleaseBigBlock + * + * Releases the specified block. + */ +void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock) +{ + MappedPage *page; + + if (pBlock == NULL) + return; + + page = BIGBLOCKFILE_GetPageFromPointer(This, pBlock); + + if (page == NULL) + return; + + BIGBLOCKFILE_ReleaseMappedPage(This, page); +} + +/****************************************************************************** + * BIGBLOCKFILE_SetSize + * + * Sets the size of the file. + * + */ +void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize) +{ + if (This->filesize.u.LowPart == newSize.u.LowPart) + return; + + Print(MAX_TRACE, ("from %lu to %lu\n", This->filesize.u.LowPart, newSize.u.LowPart)); + /* + * unmap all views, must be done before call to SetEndFile + */ + BIGBLOCKFILE_UnmapAllMappedPages(This); + + if (This->fileBased) + { + char buf[10]; + + /* + * close file-mapping object, must be done before call to SetEndFile + */ + CloseHandle(This->hfilemap); + This->hfilemap = 0; + + /* + * BEGIN HACK + * This fixes a bug when saving through smbfs. + * smbmount a Windows shared directory, save a structured storage file + * to that dir: crash. + * + * The problem is that the SetFilePointer-SetEndOfFile combo below + * doesn't always succeed. The file is not grown. It seems like the + * operation is cached. By doing the WriteFile, the file is actually + * grown on disk. + * This hack is only needed when saving to smbfs. + */ + memset(buf, '0', 10); + SetFilePointer(This->hfile, newSize.u.LowPart, NULL, FILE_BEGIN); + WriteFile(This->hfile, buf, 10, NULL, NULL); + /* + * END HACK + */ + + /* + * set the new end of file + */ + SetFilePointer(This->hfile, newSize.u.LowPart, NULL, FILE_BEGIN); + SetEndOfFile(This->hfile); + + /* + * re-create the file mapping object + */ + This->hfilemap = CreateFileMappingA(This->hfile, + NULL, + This->flProtect, + 0, 0, + NULL); + } + else + { + GlobalUnlock(This->hbytearray); + + /* + * Resize the byte array object. + */ + ILockBytes_SetSize(This->pLkbyt, newSize); + + /* + * Re-acquire the handle, it may have changed. + */ + GetHGlobalFromILockBytes(This->pLkbyt, &This->hbytearray); + This->pbytearray = GlobalLock(This->hbytearray); + } + + This->filesize.u.LowPart = newSize.u.LowPart; + This->filesize.u.HighPart = newSize.u.HighPart; + + BIGBLOCKFILE_RemapAllMappedPages(This); +} + +/****************************************************************************** + * BIGBLOCKFILE_GetSize + * + * Returns the size of the file. + * + */ +ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This) +{ + return This->filesize; +} + +/****************************************************************************** + * BIGBLOCKFILE_AccessCheck [PRIVATE] + * + * block_index is the index within the page. + */ +static BOOL BIGBLOCKFILE_AccessCheck(MappedPage *page, ULONG block_index, + DWORD desired_access) +{ + assert(block_index < BLOCKS_PER_PAGE); + + if (desired_access == FILE_MAP_READ) + { + if (BIGBLOCKFILE_TestBit(&page->writable_blocks, block_index)) + return FALSE; + + BIGBLOCKFILE_SetBit(&page->readable_blocks, block_index); + } + else + { + assert(desired_access == FILE_MAP_WRITE); + + if (BIGBLOCKFILE_TestBit(&page->readable_blocks, block_index)) + return FALSE; + + BIGBLOCKFILE_SetBit(&page->writable_blocks, block_index); + } + + return TRUE; +} + +/****************************************************************************** + * BIGBLOCKFILE_GetBigBlockPointer [PRIVATE] + * + * Returns a pointer to the specified block. + */ +static void* BIGBLOCKFILE_GetBigBlockPointer( + LPBIGBLOCKFILE This, + ULONG block_index, + DWORD desired_access) +{ + DWORD page_index = block_index / BLOCKS_PER_PAGE; + DWORD block_on_page = block_index % BLOCKS_PER_PAGE; + + MappedPage *page = BIGBLOCKFILE_GetMappedView(This, page_index); + if (!page || !page->lpBytes) return NULL; + + if (!BIGBLOCKFILE_AccessCheck(page, block_on_page, desired_access)) + { + BIGBLOCKFILE_ReleaseMappedPage(This, page); + return NULL; + } + + return (LPBYTE)page->lpBytes + (block_on_page * This->blocksize); +} + +/****************************************************************************** + * BIGBLOCKFILE_GetMappedPageFromPointer [PRIVATE] + * + * pBlock is a pointer to a block on a page. + * The page has to be on the in-use list. (As oppsed to the victim list.) + * + * Does not increment the usage count. + */ +static MappedPage *BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This, + void *pBlock) +{ + MappedPage *page; + + for (page = This->maplist; page != NULL; page = page->next) + { + if ((LPBYTE)pBlock >= (LPBYTE)page->lpBytes + && (LPBYTE)pBlock <= (LPBYTE)page->lpBytes + PAGE_SIZE) + break; + + } + + return page; +} + +/****************************************************************************** + * BIGBLOCKFILE_FindPageInList [PRIVATE] + * + */ +static MappedPage *BIGBLOCKFILE_FindPageInList(MappedPage *head, + ULONG page_index) +{ + for (; head != NULL; head = head->next) + { + if (head->page_index == page_index) + { + InterlockedIncrement(&head->refcnt); + break; + } + } + + return head; + +} + +static void BIGBLOCKFILE_UnlinkPage(MappedPage *page) +{ + if (page->next) page->next->prev = page->prev; + if (page->prev) page->prev->next = page->next; +} + +static void BIGBLOCKFILE_LinkHeadPage(MappedPage **head, MappedPage *page) +{ + if (*head) (*head)->prev = page; + page->next = *head; + page->prev = NULL; + *head = page; +} + +/****************************************************************************** + * BIGBLOCKFILE_GetMappedView [PRIVATE] + * + * Gets the page requested if it is already mapped. + * If it's not already mapped, this method will map it + */ +static void * BIGBLOCKFILE_GetMappedView( + LPBIGBLOCKFILE This, + DWORD page_index) +{ + MappedPage *page; + + page = BIGBLOCKFILE_FindPageInList(This->maplist, page_index); + if (!page) + { + page = BIGBLOCKFILE_FindPageInList(This->victimhead, page_index); + if (page) + { + This->num_victim_pages--; + + BIGBLOCKFILE_Zero(&page->readable_blocks); + BIGBLOCKFILE_Zero(&page->writable_blocks); + } + } + + if (page) + { + /* If the page is not already at the head of the list, move + * it there. (Also moves pages from victim to main list.) */ + if (This->maplist != page) + { + if (This->victimhead == page) This->victimhead = page->next; + if (This->victimtail == page) This->victimtail = page->prev; + + BIGBLOCKFILE_UnlinkPage(page); + + BIGBLOCKFILE_LinkHeadPage(&This->maplist, page); + } + + return page; + } + + page = BIGBLOCKFILE_CreatePage(This, page_index); + if (!page) return NULL; + + BIGBLOCKFILE_LinkHeadPage(&This->maplist, page); + + return page; +} + +static BOOL BIGBLOCKFILE_MapPage(LPBIGBLOCKFILE This, MappedPage *page) +{ + DWORD lowoffset = PAGE_SIZE * page->page_index; + + if (This->fileBased) + { + DWORD numBytesToMap; + DWORD desired_access; + + if (lowoffset + PAGE_SIZE > This->filesize.u.LowPart) + numBytesToMap = This->filesize.u.LowPart - lowoffset; + else + numBytesToMap = PAGE_SIZE; + + if (This->flProtect == PAGE_READONLY) + desired_access = FILE_MAP_READ; + else + desired_access = FILE_MAP_WRITE; + + page->lpBytes = MapViewOfFile(This->hfilemap, desired_access, 0, + lowoffset, numBytesToMap); + } + else + { + page->lpBytes = (LPBYTE)This->pbytearray + lowoffset; + } + + Print(MAX_TRACE, ("mapped page %lu to %p\n", page->page_index, page->lpBytes)); + + return page->lpBytes != NULL; +} + +static MappedPage *BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This, + ULONG page_index) +{ + MappedPage *page; + + page = HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage)); + if (page == NULL) + return NULL; + + page->page_index = page_index; + page->refcnt = 1; + + page->next = NULL; + page->prev = NULL; + + BIGBLOCKFILE_MapPage(This, page); + + BIGBLOCKFILE_Zero(&page->readable_blocks); + BIGBLOCKFILE_Zero(&page->writable_blocks); + + return page; +} + +static void BIGBLOCKFILE_UnmapPage(LPBIGBLOCKFILE This, MappedPage *page) +{ + Print(MAX_TRACE, ("%ld at %p\n", page->page_index, page->lpBytes)); + if (page->refcnt > 0) + Print(MIN_TRACE, ("unmapping inuse page %p\n", page->lpBytes)); + + if (This->fileBased && page->lpBytes) + UnmapViewOfFile(page->lpBytes); + + page->lpBytes = NULL; +} + +static void BIGBLOCKFILE_DeletePage(LPBIGBLOCKFILE This, MappedPage *page) +{ + BIGBLOCKFILE_UnmapPage(This, page); + + HeapFree(GetProcessHeap(), 0, page); +} + +/****************************************************************************** + * BIGBLOCKFILE_ReleaseMappedPage [PRIVATE] + * + * Decrements the reference count of the mapped page. + */ +static void BIGBLOCKFILE_ReleaseMappedPage( + LPBIGBLOCKFILE This, + MappedPage *page) +{ + assert(This != NULL); + assert(page != NULL); + + /* If the page is no longer refenced, move it to the victim list. + * If the victim list is too long, kick somebody off. */ + if (!InterlockedDecrement(&page->refcnt)) + { + if (This->maplist == page) This->maplist = page->next; + + BIGBLOCKFILE_UnlinkPage(page); + + if (MAX_VICTIM_PAGES > 0) + { + if (This->num_victim_pages >= MAX_VICTIM_PAGES) + { + MappedPage *victim = This->victimtail; + if (victim) + { + This->victimtail = victim->prev; + if (This->victimhead == victim) + This->victimhead = victim->next; + + BIGBLOCKFILE_UnlinkPage(victim); + BIGBLOCKFILE_DeletePage(This, victim); + } + } + else This->num_victim_pages++; + + BIGBLOCKFILE_LinkHeadPage(&This->victimhead, page); + if (This->victimtail == NULL) This->victimtail = page; + } + else + BIGBLOCKFILE_DeletePage(This, page); + } +} + +static void BIGBLOCKFILE_DeleteList(LPBIGBLOCKFILE This, MappedPage *list) +{ + while (list != NULL) + { + MappedPage *next = list->next; + + BIGBLOCKFILE_DeletePage(This, list); + + list = next; + } +} + +/****************************************************************************** + * BIGBLOCKFILE_FreeAllMappedPages [PRIVATE] + * + * Unmap all currently mapped pages. + * Empty mapped pages list. + */ +static void BIGBLOCKFILE_FreeAllMappedPages( + LPBIGBLOCKFILE This) +{ + BIGBLOCKFILE_DeleteList(This, This->maplist); + BIGBLOCKFILE_DeleteList(This, This->victimhead); + + This->maplist = NULL; + This->victimhead = NULL; + This->victimtail = NULL; + This->num_victim_pages = 0; +} + +static void BIGBLOCKFILE_UnmapList(LPBIGBLOCKFILE This, MappedPage *list) +{ + for (; list != NULL; list = list->next) + { + BIGBLOCKFILE_UnmapPage(This, list); + } +} + +static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This) +{ + BIGBLOCKFILE_UnmapList(This, This->maplist); + BIGBLOCKFILE_UnmapList(This, This->victimhead); +} + +static void BIGBLOCKFILE_RemapList(LPBIGBLOCKFILE This, MappedPage *list) +{ + while (list != NULL) + { + MappedPage *next = list->next; + + if (list->page_index * PAGE_SIZE > This->filesize.u.LowPart) + { + Print(MAX_TRACE, ("discarding %lu\n", list->page_index)); + + /* page is entirely outside of the file, delete it */ + BIGBLOCKFILE_UnlinkPage(list); + BIGBLOCKFILE_DeletePage(This, list); + } + else + { + /* otherwise, remap it */ + BIGBLOCKFILE_MapPage(This, list); + } + + list = next; + } +} + +static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This) +{ + BIGBLOCKFILE_RemapList(This, This->maplist); + BIGBLOCKFILE_RemapList(This, This->victimhead); +} + +/**************************************************************************** + * BIGBLOCKFILE_GetProtectMode + * + * This function will return a protection mode flag for a file-mapping object + * from the open flags of a file. + */ +static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags) +{ + if (openFlags & (STGM_WRITE | STGM_READWRITE)) + return PAGE_READWRITE; + else + return PAGE_READONLY; +} diff --git a/reactos/lib/ole32/stg_stream.c b/reactos/lib/ole32/stg_stream.c new file mode 100644 index 00000000000..fb4b9ab68cf --- /dev/null +++ b/reactos/lib/ole32/stg_stream.c @@ -0,0 +1,835 @@ +/* + * Compound Storage (32 bit version) + * Stream implementation + * + * This file contains the implementation of the stream interface + * for streams contained in a compound storage. + * + * Copyright 1999 Francis Beaudet + * Copyright 1999 Thuy Nguyen + */ +#include +#include +#include + +#include +#include +#include +#include "storage32.h" + +#include + + +/* + * Virtual function table for the StgStreamImpl class. + */ +static ICOM_VTABLE(IStream) StgStreamImpl_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + StgStreamImpl_QueryInterface, + StgStreamImpl_AddRef, + StgStreamImpl_Release, + StgStreamImpl_Read, + StgStreamImpl_Write, + StgStreamImpl_Seek, + StgStreamImpl_SetSize, + StgStreamImpl_CopyTo, + StgStreamImpl_Commit, + StgStreamImpl_Revert, + StgStreamImpl_LockRegion, + StgStreamImpl_UnlockRegion, + StgStreamImpl_Stat, + StgStreamImpl_Clone +}; + +/****************************************************************************** +** StgStreamImpl implementation +*/ + +/*** + * This is the constructor for the StgStreamImpl class. + * + * Params: + * parentStorage - Pointer to the storage that contains the stream to open + * ownerProperty - Index of the property that points to this stream. + */ +StgStreamImpl* StgStreamImpl_Construct( + StorageBaseImpl* parentStorage, + DWORD grfMode, + ULONG ownerProperty) +{ + StgStreamImpl* newStream; + + newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(StgStreamImpl)); + + if (newStream!=0) + { + /* + * Set-up the virtual function table and reference count. + */ + ICOM_VTBL(newStream) = &StgStreamImpl_Vtbl; + newStream->ref = 0; + + /* + * We want to nail-down the reference to the storage in case the + * stream out-lives the storage in the client application. + */ + newStream->parentStorage = parentStorage; + IStorage_AddRef((IStorage*)newStream->parentStorage); + + newStream->grfMode = grfMode; + newStream->ownerProperty = ownerProperty; + + /* + * Start the stream at the begining. + */ + newStream->currentPosition.u.HighPart = 0; + newStream->currentPosition.u.LowPart = 0; + + /* + * Initialize the rest of the data. + */ + newStream->streamSize.u.HighPart = 0; + newStream->streamSize.u.LowPart = 0; + newStream->bigBlockChain = 0; + newStream->smallBlockChain = 0; + + /* + * Read the size from the property and determine if the blocks forming + * this stream are large or small. + */ + StgStreamImpl_OpenBlockChain(newStream); + } + + return newStream; +} + +/*** + * This is the destructor of the StgStreamImpl class. + * + * This method will clean-up all the resources used-up by the given StgStreamImpl + * class. The pointer passed-in to this function will be freed and will not + * be valid anymore. + */ +void StgStreamImpl_Destroy(StgStreamImpl* This) +{ + Print(MAX_TRACE, ("(%p)\n", This)); + + /* + * Release the reference we are holding on the parent storage. + */ + IStorage_Release((IStorage*)This->parentStorage); + This->parentStorage = 0; + + /* + * Make sure we clean-up the block chain stream objects that we were using. + */ + if (This->bigBlockChain != 0) + { + BlockChainStream_Destroy(This->bigBlockChain); + This->bigBlockChain = 0; + } + + if (This->smallBlockChain != 0) + { + SmallBlockChainStream_Destroy(This->smallBlockChain); + This->smallBlockChain = 0; + } + + /* + * Finally, free the memory used-up by the class. + */ + HeapFree(GetProcessHeap(), 0, This); +} + +/*** + * This implements the IUnknown method QueryInterface for this + * class + */ +HRESULT WINAPI StgStreamImpl_QueryInterface( + IStream* iface, + REFIID riid, /* [in] */ + void** ppvObject) /* [iid_is][out] */ +{ + StgStreamImpl* const This=(StgStreamImpl*)iface; + + /* + * Perform a sanity check on the parameters. + */ + if (ppvObject==0) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = (IStream*)This; + } + else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0) + { + *ppvObject = (IStream*)This; + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* + * Query Interface always increases the reference count by one when it is + * successful + */ + StgStreamImpl_AddRef(iface); + + return S_OK;; +} + +/*** + * This implements the IUnknown method AddRef for this + * class + */ +ULONG WINAPI StgStreamImpl_AddRef( + IStream* iface) +{ + StgStreamImpl* const This=(StgStreamImpl*)iface; + + This->ref++; + + return This->ref; +} + +/*** + * This implements the IUnknown method Release for this + * class + */ +ULONG WINAPI StgStreamImpl_Release( + IStream* iface) +{ + StgStreamImpl* const This=(StgStreamImpl*)iface; + + ULONG newRef; + + This->ref--; + + newRef = This->ref; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (newRef==0) + { + StgStreamImpl_Destroy(This); + } + + return newRef; +} + +/*** + * This method will open the block chain pointed by the property + * that describes the stream. + * If the stream's size is null, no chain is opened. + */ +void StgStreamImpl_OpenBlockChain( + StgStreamImpl* This) +{ + StgProperty curProperty; + BOOL readSucessful; + + /* + * Make sure no old object is staying behind. + */ + if (This->smallBlockChain != 0) + { + SmallBlockChainStream_Destroy(This->smallBlockChain); + This->smallBlockChain = 0; + } + + if (This->bigBlockChain != 0) + { + BlockChainStream_Destroy(This->bigBlockChain); + This->bigBlockChain = 0; + } + + /* + * Read the information from the property. + */ + readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, + This->ownerProperty, + &curProperty); + + if (readSucessful) + { + This->streamSize = curProperty.size; + + /* + * This code supports only streams that are <32 bits in size. + */ + assert(This->streamSize.u.HighPart == 0); + + if(curProperty.startingBlock == BLOCK_END_OF_CHAIN) + { + assert( (This->streamSize.u.HighPart == 0) && (This->streamSize.u.LowPart == 0) ); + } + else + { + if ( (This->streamSize.u.HighPart == 0) && + (This->streamSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) + { + This->smallBlockChain = SmallBlockChainStream_Construct( + This->parentStorage->ancestorStorage, + This->ownerProperty); + } + else + { + This->bigBlockChain = BlockChainStream_Construct( + This->parentStorage->ancestorStorage, + NULL, + This->ownerProperty); + } + } + } +} + +/*** + * This method is part of the ISequentialStream interface. + * + * If reads a block of information from the stream at the current + * position. It then moves the current position at the end of the + * read block + * + * See the documentation of ISequentialStream for more info. + */ +HRESULT WINAPI StgStreamImpl_Read( + IStream* iface, + void* pv, /* [length_is][size_is][out] */ + ULONG cb, /* [in] */ + ULONG* pcbRead) /* [out] */ +{ + StgStreamImpl* const This=(StgStreamImpl*)iface; + + ULONG bytesReadBuffer; + ULONG bytesToReadFromBuffer; + + Print(MAX_TRACE, ("(%p, %p, %ld, %p)\n", + iface, pv, cb, pcbRead)); + + /* + * If the caller is not interested in the nubmer of bytes read, + * we use another buffer to avoid "if" statements in the code. + */ + if (pcbRead==0) + pcbRead = &bytesReadBuffer; + + /* + * Using the known size of the stream, calculate the number of bytes + * to read from the block chain + */ + bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb); + + /* + * Depending on the type of chain that was opened when the stream was constructed, + * we delegate the work to the method that read the block chains. + */ + if (This->smallBlockChain!=0) + { + SmallBlockChainStream_ReadAt(This->smallBlockChain, + This->currentPosition, + bytesToReadFromBuffer, + pv, + pcbRead); + + } + else if (This->bigBlockChain!=0) + { + BlockChainStream_ReadAt(This->bigBlockChain, + This->currentPosition, + bytesToReadFromBuffer, + pv, + pcbRead); + } + else + { + /* + * Small and big block chains are both NULL. This case will happen + * when a stream starts with BLOCK_END_OF_CHAIN and has size zero. + */ + + *pcbRead = 0; + return S_OK; + } + + /* + * We should always be able to read the proper amount of data from the + * chain. + */ + assert(bytesToReadFromBuffer == *pcbRead); + + /* + * Advance the pointer for the number of positions read. + */ + This->currentPosition.u.LowPart += *pcbRead; + + /* + * The function returns S_OK if the buffer was filled completely + * it returns S_FALSE if the end of the stream is reached before the + * buffer is filled + */ + if(*pcbRead == cb) + return S_OK; + + return S_FALSE; +} + +/*** + * This method is part of the ISequentialStream interface. + * + * It writes a block of information to the stream at the current + * position. It then moves the current position at the end of the + * written block. If the stream is too small to fit the block, + * the stream is grown to fit. + * + * See the documentation of ISequentialStream for more info. + */ +HRESULT WINAPI StgStreamImpl_Write( + IStream* iface, + const void* pv, /* [size_is][in] */ + ULONG cb, /* [in] */ + ULONG* pcbWritten) /* [out] */ +{ + StgStreamImpl* const This=(StgStreamImpl*)iface; + + ULARGE_INTEGER newSize; + ULONG bytesWritten = 0; + + Print(MAX_TRACE, ("(%p, %p, %ld, %p)\n", + iface, pv, cb, pcbWritten)); + + /* + * Do we have permission to write to this stream? + */ + if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE))) { + return STG_E_ACCESSDENIED; + } + + /* + * If the caller is not interested in the number of bytes written, + * we use another buffer to avoid "if" statements in the code. + */ + if (pcbWritten == 0) + pcbWritten = &bytesWritten; + + /* + * Initialize the out parameter + */ + *pcbWritten = 0; + + if (cb == 0) + { + return S_OK; + } + else + { + newSize.u.HighPart = 0; + newSize.u.LowPart = This->currentPosition.u.LowPart + cb; + } + + /* + * Verify if we need to grow the stream + */ + if (newSize.u.LowPart > This->streamSize.u.LowPart) + { + /* grow stream */ + IStream_SetSize(iface, newSize); + } + + /* + * Depending on the type of chain that was opened when the stream was constructed, + * we delegate the work to the method that readwrites to the block chains. + */ + if (This->smallBlockChain!=0) + { + SmallBlockChainStream_WriteAt(This->smallBlockChain, + This->currentPosition, + cb, + pv, + pcbWritten); + + } + else if (This->bigBlockChain!=0) + { + BlockChainStream_WriteAt(This->bigBlockChain, + This->currentPosition, + cb, + pv, + pcbWritten); + } + else + assert(FALSE); + + /* + * Advance the position pointer for the number of positions written. + */ + This->currentPosition.u.LowPart += *pcbWritten; + + return S_OK; +} + +/*** + * This method is part of the IStream interface. + * + * It will move the current stream pointer according to the parameters + * given. + * + * See the documentation of IStream for more info. + */ +HRESULT WINAPI StgStreamImpl_Seek( + IStream* iface, + LARGE_INTEGER dlibMove, /* [in] */ + DWORD dwOrigin, /* [in] */ + ULARGE_INTEGER* plibNewPosition) /* [out] */ +{ + StgStreamImpl* const This=(StgStreamImpl*)iface; + + ULARGE_INTEGER newPosition; + LARGE_INTEGER Position; + + Print(MAX_TRACE, ("(%p, %ld, %ld, %p)\n", + iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition)); + + /* + * The caller is allowed to pass in NULL as the new position return value. + * If it happens, we assign it to a dynamic variable to avoid special cases + * in the code below. + */ + if (plibNewPosition == 0) + { + plibNewPosition = &newPosition; + } + + /* + * The file pointer is moved depending on the given "function" + * parameter. + */ + switch (dwOrigin) + { + case STREAM_SEEK_SET: + plibNewPosition->u.HighPart = 0; + plibNewPosition->u.LowPart = 0; + break; + case STREAM_SEEK_CUR: + *plibNewPosition = This->currentPosition; + break; + case STREAM_SEEK_END: + *plibNewPosition = This->streamSize; + break; + default: + return STG_E_INVALIDFUNCTION; + } + + Position = RtlLargeIntegerAdd( *((PLARGE_INTEGER)plibNewPosition), dlibMove ); + + plibNewPosition->QuadPart = Position.QuadPart; + + /* + * tell the caller what we calculated + */ + This->currentPosition = *plibNewPosition; + + return S_OK; +} + +/*** + * This method is part of the IStream interface. + * + * It will change the size of a stream. + * + * TODO: Switch from small blocks to big blocks and vice versa. + * + * See the documentation of IStream for more info. + */ +HRESULT WINAPI StgStreamImpl_SetSize( + IStream* iface, + ULARGE_INTEGER libNewSize) /* [in] */ +{ + StgStreamImpl* const This=(StgStreamImpl*)iface; + + StgProperty curProperty; + BOOL Success; + + Print(MAX_TRACE, ("(%p, %ld)\n", iface, libNewSize.u.LowPart)); + + /* + * As documented. + */ + if (libNewSize.u.HighPart != 0) + return STG_E_INVALIDFUNCTION; + + /* + * Do we have permission? + */ + if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE))) + return STG_E_ACCESSDENIED; + + if (This->streamSize.u.LowPart == libNewSize.u.LowPart) + return S_OK; + + /* + * This will happen if we're creating a stream + */ + if ((This->smallBlockChain == 0) && (This->bigBlockChain == 0)) + { + if (libNewSize.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) + { + This->smallBlockChain = SmallBlockChainStream_Construct( + This->parentStorage->ancestorStorage, + This->ownerProperty); + } + else + { + This->bigBlockChain = BlockChainStream_Construct( + This->parentStorage->ancestorStorage, + NULL, + This->ownerProperty); + } + } + + /* + * Read this stream's property to see if it's small blocks or big blocks + */ + Success = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, + This->ownerProperty, + &curProperty); + /* + * Determine if we have to switch from small to big blocks or vice versa + */ + if ( (This->smallBlockChain!=0) && + (curProperty.size.u.LowPart < LIMIT_TO_USE_SMALL_BLOCK) ) + { + if (libNewSize.u.LowPart >= LIMIT_TO_USE_SMALL_BLOCK) + { + /* + * Transform the small block chain into a big block chain + */ + This->bigBlockChain = Storage32Impl_SmallBlocksToBigBlocks( + This->parentStorage->ancestorStorage, + &This->smallBlockChain); + } + } + + if (This->smallBlockChain!=0) + { + Success = SmallBlockChainStream_SetSize(This->smallBlockChain, libNewSize); + } + else + { + Success = BlockChainStream_SetSize(This->bigBlockChain, libNewSize); + } + + /* + * Write to the property the new information about this stream + */ + Success = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, + This->ownerProperty, + &curProperty); + + curProperty.size.u.HighPart = libNewSize.u.HighPart; + curProperty.size.u.LowPart = libNewSize.u.LowPart; + + if (Success) + { + StorageImpl_WriteProperty(This->parentStorage->ancestorStorage, + This->ownerProperty, + &curProperty); + } + + This->streamSize = libNewSize; + + return S_OK; +} + +/*** + * This method is part of the IStream interface. + * + * It will copy the 'cb' Bytes to 'pstm' IStream. + * + * See the documentation of IStream for more info. + */ +HRESULT WINAPI StgStreamImpl_CopyTo( + IStream* iface, + IStream* pstm, /* [unique][in] */ + ULARGE_INTEGER cb, /* [in] */ + ULARGE_INTEGER* pcbRead, /* [out] */ + ULARGE_INTEGER* pcbWritten) /* [out] */ +{ + HRESULT hr = S_OK; + BYTE tmpBuffer[128]; + ULONG bytesRead, bytesWritten, copySize; + ULARGE_INTEGER totalBytesRead; + ULARGE_INTEGER totalBytesWritten; + + Print(MAX_TRACE, ("(%p, %p, %ld, %p, %p)\n", + iface, pstm, cb.u.LowPart, pcbRead, pcbWritten)); + + /* + * Sanity check + */ + if ( pstm == 0 ) + return STG_E_INVALIDPOINTER; + + totalBytesRead.u.LowPart = totalBytesRead.u.HighPart = 0; + totalBytesWritten.u.LowPart = totalBytesWritten.u.HighPart = 0; + + /* + * use stack to store data temporarly + * there is surely more performant way of doing it, for now this basic + * implementation will do the job + */ + while ( cb.u.LowPart > 0 ) + { + if ( cb.u.LowPart >= 128 ) + copySize = 128; + else + copySize = cb.u.LowPart; + + IStream_Read(iface, tmpBuffer, copySize, &bytesRead); + + totalBytesRead.u.LowPart += bytesRead; + + IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten); + + totalBytesWritten.u.LowPart += bytesWritten; + + /* + * Check that read & write operations were succesfull + */ + if (bytesRead != bytesWritten) + { + hr = STG_E_MEDIUMFULL; + break; + } + + if (bytesRead!=copySize) + cb.u.LowPart = 0; + else + cb.u.LowPart -= bytesRead; + } + + /* + * Update number of bytes read and written + */ + if (pcbRead) + { + pcbRead->u.LowPart = totalBytesRead.u.LowPart; + pcbRead->u.HighPart = totalBytesRead.u.HighPart; + } + + if (pcbWritten) + { + pcbWritten->u.LowPart = totalBytesWritten.u.LowPart; + pcbWritten->u.HighPart = totalBytesWritten.u.HighPart; + } + return hr; +} + +/*** + * This method is part of the IStream interface. + * + * For streams contained in structured storages, this method + * does nothing. This is what the documentation tells us. + * + * See the documentation of IStream for more info. + */ +HRESULT WINAPI StgStreamImpl_Commit( + IStream* iface, + DWORD grfCommitFlags) /* [in] */ +{ + return S_OK; +} + +/*** + * This method is part of the IStream interface. + * + * For streams contained in structured storages, this method + * does nothing. This is what the documentation tells us. + * + * See the documentation of IStream for more info. + */ +HRESULT WINAPI StgStreamImpl_Revert( + IStream* iface) +{ + return S_OK; +} + +HRESULT WINAPI StgStreamImpl_LockRegion( + IStream* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType) /* [in] */ +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +HRESULT WINAPI StgStreamImpl_UnlockRegion( + IStream* iface, + ULARGE_INTEGER libOffset, /* [in] */ + ULARGE_INTEGER cb, /* [in] */ + DWORD dwLockType) /* [in] */ +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/*** + * This method is part of the IStream interface. + * + * This method returns information about the current + * stream. + * + * See the documentation of IStream for more info. + */ +HRESULT WINAPI StgStreamImpl_Stat( + IStream* iface, + STATSTG* pstatstg, /* [out] */ + DWORD grfStatFlag) /* [in] */ +{ + StgStreamImpl* const This=(StgStreamImpl*)iface; + + StgProperty curProperty; + BOOL readSucessful; + + /* + * Read the information from the property. + */ + readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage, + This->ownerProperty, + &curProperty); + + if (readSucessful) + { + StorageUtl_CopyPropertyToSTATSTG(pstatstg, + &curProperty, + grfStatFlag); + + pstatstg->grfMode = This->grfMode; + + return S_OK; + } + + return E_FAIL; +} + +HRESULT WINAPI StgStreamImpl_Clone( + IStream* iface, + IStream** ppstm) /* [out] */ +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} diff --git a/reactos/lib/ole32/storage.c b/reactos/lib/ole32/storage.c index 3428a8f1dcc..e0a2f00d56a 100644 --- a/reactos/lib/ole32/storage.c +++ b/reactos/lib/ole32/storage.c @@ -1,166 +1,778 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib\ole32\Storage.c - * PURPOSE: Storage helper functions - * PROGRAMMER: jurgen van gael [jurgen.vangael@student.kuleuven.ac.be] - * UPDATE HISTORY: - * Created 12/05/2001 +/* Compound Storage + * + * Implemented using the documentation of the LAOLA project at + * + * (Thanks to Martin Schwartz ) + * + * Copyright 1998 Marcus Meissner */ -/******************************************************************** + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +struct storage_header { + BYTE magic[8]; /* 00: magic */ + BYTE unknown1[36]; /* 08: unknown */ + DWORD num_of_bbd_blocks;/* 2C: length of big datablocks */ + DWORD root_startblock;/* 30: root storage first big block */ + DWORD unknown2[2]; /* 34: unknown */ + DWORD sbd_startblock; /* 3C: small block depot first big block */ + DWORD unknown3[3]; /* 40: unknown */ + DWORD bbd_list[109]; /* 4C: big data block list (up to end of sector)*/ +}; +struct storage_pps_entry { + WCHAR pps_rawname[32];/* 00: \0 terminated widechar name */ + WORD pps_sizeofname; /* 40: namelength in bytes */ + BYTE pps_type; /* 42: flags, 1 storage/dir, 2 stream, 5 root */ + BYTE pps_unknown0; /* 43: unknown */ + DWORD pps_prev; /* 44: previous pps */ + DWORD pps_next; /* 48: next pps */ + DWORD pps_dir; /* 4C: directory pps */ + GUID pps_guid; /* 50: class ID */ + DWORD pps_unknown1; /* 60: unknown */ + FILETIME pps_ft1; /* 64: filetime1 */ + FILETIME pps_ft2; /* 70: filetime2 */ + DWORD pps_sb; /* 74: data startblock */ + DWORD pps_size; /* 78: datalength. (<0x1000)?small:big blocks*/ + DWORD pps_unknown2; /* 7C: unknown */ +}; + +#define STORAGE_CHAINENTRY_FAT 0xfffffffd +#define STORAGE_CHAINENTRY_ENDOFCHAIN 0xfffffffe +#define STORAGE_CHAINENTRY_FREE 0xffffffff -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. +//static const BYTE STORAGE_magic[8] ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1}; +//static const BYTE STORAGE_notmagic[8]={0x0e,0x11,0xfc,0x0d,0xd0,0xcf,0x11,0xe0}; +//static const BYTE STORAGE_oldmagic[8]={0xd0,0xcf,0x11,0xe0,0x0e,0x11,0xfc,0x0d}; -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. +#define BIGSIZE 512 +#define SMALLSIZE 64 -You should have received a copy of the GNU Library General Public -License along with this library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. +#define SMALLBLOCKS_PER_BIGBLOCK (BIGSIZE/SMALLSIZE) + +#define READ_HEADER assert(STORAGE_get_big_block(hf,-1,(LPBYTE)&sth));assert(!memcmp(STORAGE_magic,sth.magic,sizeof(STORAGE_magic))); +static ICOM_VTABLE(IStorage16) stvt16; +static ICOM_VTABLE(IStorage16) *segstvt16 = NULL; +static ICOM_VTABLE(IStream16) strvt16; +static ICOM_VTABLE(IStream16) *segstrvt16 = NULL; + +/*ULONG WINAPI IStorage16_AddRef(LPSTORAGE16 this);*/ +static void _create_istorage16(LPSTORAGE16 *stg); +static void _create_istream16(LPSTREAM16 *str); + +#define IMPLEMENTED 1 -********************************************************************/ -#include "Ole32.h" - -/*WINOLEAPI StgCreatePropStg( IUnknown* pUnk, REFFMTID fmtid, const CLSID *pclsid, DWORD grfFlags, DWORD dwReserved, IPropertyStorage **ppPropStg ){return S_OK;} -WINOLEAPI StgOpenPropStg( IUnknown* pUnk, REFFMTID fmtid, DWORD grfFlags, DWORD dwReserved, IPropertyStorage **ppPropStg ){return S_OK;} -WINOLEAPI StgCreatePropSetStg( IStorage *pStorage, DWORD dwReserved, IPropertySetStorage **ppPropSetStg){return S_OK;} - -WINOLEAPI FmtIdToPropStgName( const FMTID *pfmtid, LPOLESTR oszName ){return S_OK;} -WINOLEAPI PropStgNameToFmtId( const LPOLESTR oszName, FMTID *pfmtid ){return S_OK;} - -WINOLEAPI StgSetTimes( - WCHAR const *lpszName, - FILETIME const *pctime, - FILETIME const *patime, - FILETIME const *pmtime -){return S_OK;} - -// helper functions -WINOLEAPI ReadClassStg(IN LPSTORAGE pStg, OUT CLSID FAR* pclsid){return S_OK;} -WINOLEAPI WriteClassStg(IN LPSTORAGE pStg, IN REFCLSID rclsid){return S_OK;} -WINOLEAPI ReadClassStm(IN LPSTREAM pStm, OUT CLSID FAR* pclsid){return S_OK;} -WINOLEAPI WriteClassStm(IN LPSTREAM pStm, IN REFCLSID rclsid){return S_OK;} -WINOLEAPI WriteFmtUserTypeStg (IN LPSTORAGE pstg, IN CLIPFORMAT cf, IN LPOLESTR lpszUserType){return S_OK;} -WINOLEAPI ReadFmtUserTypeStg (IN LPSTORAGE pstg, OUT CLIPFORMAT FAR* pcf, OUT LPOLESTR FAR* lplpszUserType){return S_OK;} - - - -WINOLEAPI StgCreateDocfile(IN const OLECHAR FAR* pwcsName, - IN DWORD grfMode, - IN DWORD reserved, - OUT IStorage FAR * FAR *ppstgOpen) -{ - return S_OK; +/****************************************************************************** + * STORAGE_get_big_block [Internal] + * + * Reading OLE compound storage + */ +static BOOL +STORAGE_get_big_block(HFILE hf,int n,BYTE *block) { + assert(n>=-1); + if (-1==_llseek(hf,(n+1)*BIGSIZE,SEEK_SET)) { + Print(MID_TRACE, (" seek failed (%ld)\n",GetLastError())); + return FALSE; + } + assert((n+1)*BIGSIZE==_llseek(hf,0,SEEK_CUR)); + if (BIGSIZE!=_lread(hf,block,BIGSIZE)) { + Print(MID_TRACE, ("(block size %d): read didn't read (%ld)\n",n,GetLastError())); + assert(0); + return FALSE; + } + return TRUE; } -WINOLEAPI StgCreateDocfileOnILockBytes(IN ILockBytes FAR *plkbyt, - IN DWORD grfMode, - IN DWORD reserved, - OUT IStorage FAR * FAR *ppstgOpen) -{ - return S_OK; +/****************************************************************************** + * STORAGE_put_big_block [INTERNAL] + */ +static BOOL +STORAGE_put_big_block(HFILE hf,int n,BYTE *block) { + assert(n>=-1); + if (-1==_llseek(hf,(n+1)*BIGSIZE,SEEK_SET)) { + Print(MID_TRACE, (" seek failed (%ld)\n",GetLastError())); + return FALSE; + } + assert((n+1)*BIGSIZE==_llseek(hf,0,SEEK_CUR)); + if (BIGSIZE!=_lwrite(hf,block,BIGSIZE)) { + Print(MID_TRACE, (" write failed (%ld)\n",GetLastError())); + return FALSE; + } + return TRUE; +} + +/****************************************************************************** + * STORAGE_get_next_big_blocknr [INTERNAL] + */ +static int +STORAGE_get_next_big_blocknr(HFILE hf,int blocknr) { + INT bbs[BIGSIZE/sizeof(INT)]; + struct storage_header sth; + + READ_HEADER; + + assert(blocknr>>7>7]==0xffffffff) + return -5; + if (!STORAGE_get_big_block(hf,sth.bbd_list[blocknr>>7],(LPBYTE)bbs)) + return -5; + assert(bbs[blocknr&0x7f]!=STORAGE_CHAINENTRY_FREE); + return bbs[blocknr&0x7f]; +} + +/****************************************************************************** + * STORAGE_get_nth_next_big_blocknr [INTERNAL] + */ +static int +STORAGE_get_nth_next_big_blocknr(HFILE hf,int blocknr,int nr) { + INT bbs[BIGSIZE/sizeof(INT)]; + int lastblock = -1; + struct storage_header sth; + + READ_HEADER; + + assert(blocknr>=0); + while (nr--) { + assert((blocknr>>7)>7]!=0xffffffff); + + /* simple caching... */ + if (lastblock!=sth.bbd_list[blocknr>>7]) { + assert(STORAGE_get_big_block(hf,sth.bbd_list[blocknr>>7],(LPBYTE)bbs)); + lastblock = sth.bbd_list[blocknr>>7]; + } + blocknr = bbs[blocknr&0x7f]; + } + return blocknr; +} + +/****************************************************************************** + * STORAGE_get_root_pps_entry [Internal] + */ +static BOOL +STORAGE_get_root_pps_entry(HFILE hf,struct storage_pps_entry *pstde) { + int blocknr,i; + BYTE block[BIGSIZE]; + struct storage_pps_entry *stde=(struct storage_pps_entry*)block; + struct storage_header sth; + + READ_HEADER; + blocknr = sth.root_startblock; + while (blocknr>=0) { + assert(STORAGE_get_big_block(hf,blocknr,block)); + for (i=0;i<4;i++) { + if (!stde[i].pps_sizeofname) + continue; + if (stde[i].pps_type==5) { + *pstde=stde[i]; + return TRUE; + } + } + blocknr=STORAGE_get_next_big_blocknr(hf,blocknr); + } + return FALSE; +} + +/****************************************************************************** + * STORAGE_get_small_block [INTERNAL] + */ +static BOOL +STORAGE_get_small_block(HFILE hf,int blocknr,BYTE *sblock) { + BYTE block[BIGSIZE]; + int bigblocknr; + struct storage_pps_entry root; + + assert(blocknr>=0); + assert(STORAGE_get_root_pps_entry(hf,&root)); + bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,root.pps_sb,blocknr/SMALLBLOCKS_PER_BIGBLOCK); + assert(bigblocknr>=0); + assert(STORAGE_get_big_block(hf,bigblocknr,block)); + + memcpy(sblock,((LPBYTE)block)+SMALLSIZE*(blocknr&(SMALLBLOCKS_PER_BIGBLOCK-1)),SMALLSIZE); + return TRUE; +} + +/****************************************************************************** + * STORAGE_put_small_block [INTERNAL] + */ +static BOOL +STORAGE_put_small_block(HFILE hf,int blocknr,BYTE *sblock) { + BYTE block[BIGSIZE]; + int bigblocknr; + struct storage_pps_entry root; + + assert(blocknr>=0); + + assert(STORAGE_get_root_pps_entry(hf,&root)); + bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,root.pps_sb,blocknr/SMALLBLOCKS_PER_BIGBLOCK); + assert(bigblocknr>=0); + assert(STORAGE_get_big_block(hf,bigblocknr,block)); + + memcpy(((LPBYTE)block)+SMALLSIZE*(blocknr&(SMALLBLOCKS_PER_BIGBLOCK-1)),sblock,SMALLSIZE); + assert(STORAGE_put_big_block(hf,bigblocknr,block)); + return TRUE; +} + +/****************************************************************************** + * STORAGE_get_next_small_blocknr [INTERNAL] + */ +static int +STORAGE_get_next_small_blocknr(HFILE hf,int blocknr) { + BYTE block[BIGSIZE]; + LPINT sbd = (LPINT)block; + int bigblocknr; + struct storage_header sth; + + READ_HEADER; + assert(blocknr>=0); + bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.sbd_startblock,blocknr/128); + assert(bigblocknr>=0); + assert(STORAGE_get_big_block(hf,bigblocknr,block)); + assert(sbd[blocknr & 127]!=STORAGE_CHAINENTRY_FREE); + return sbd[blocknr & (128-1)]; +} + +/****************************************************************************** + * STORAGE_get_nth_next_small_blocknr [INTERNAL] + */ +static int +STORAGE_get_nth_next_small_blocknr(HFILE hf,int blocknr,int nr) { + int lastblocknr; + BYTE block[BIGSIZE]; + LPINT sbd = (LPINT)block; + struct storage_header sth; + + READ_HEADER; + lastblocknr=-1; + assert(blocknr>=0); + while ((nr--) && (blocknr>=0)) { + if (lastblocknr/128!=blocknr/128) { + int bigblocknr; + bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.sbd_startblock,blocknr/128); + assert(bigblocknr>=0); + assert(STORAGE_get_big_block(hf,bigblocknr,block)); + lastblocknr = blocknr; + } + assert(lastblocknr>=0); + lastblocknr=blocknr; + blocknr=sbd[blocknr & (128-1)]; + assert(blocknr!=STORAGE_CHAINENTRY_FREE); + } + return blocknr; +} + +/****************************************************************************** + * STORAGE_get_pps_entry [INTERNAL] + */ +static int +STORAGE_get_pps_entry(HFILE hf,int n,struct storage_pps_entry *pstde) { + int blocknr; + BYTE block[BIGSIZE]; + struct storage_pps_entry *stde = (struct storage_pps_entry*)(((LPBYTE)block)+128*(n&3)); + struct storage_header sth; + + READ_HEADER; + /* we have 4 pps entries per big block */ + blocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.root_startblock,n/4); + assert(blocknr>=0); + assert(STORAGE_get_big_block(hf,blocknr,block)); + + *pstde=*stde; + return 1; +} + +/****************************************************************************** + * STORAGE_put_pps_entry [Internal] + */ +static int +STORAGE_put_pps_entry(HFILE hf,int n,struct storage_pps_entry *pstde) { + int blocknr; + BYTE block[BIGSIZE]; + struct storage_pps_entry *stde = (struct storage_pps_entry*)(((LPBYTE)block)+128*(n&3)); + struct storage_header sth; + + READ_HEADER; + + /* we have 4 pps entries per big block */ + blocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.root_startblock,n/4); + assert(blocknr>=0); + assert(STORAGE_get_big_block(hf,blocknr,block)); + *stde=*pstde; + assert(STORAGE_put_big_block(hf,blocknr,block)); + return 1; +} + +/****************************************************************************** + * STORAGE_look_for_named_pps [Internal] + */ +static int +STORAGE_look_for_named_pps(HFILE hf,int n,LPOLESTR name) { + struct storage_pps_entry stde; + int ret; + + if (n==-1) + return -1; + if (1!=STORAGE_get_pps_entry(hf,n,&stde)) + return -1; + + if (!lstrcmpW(name,stde.pps_rawname)) + return n; + if (stde.pps_prev != -1) { + ret=STORAGE_look_for_named_pps(hf,stde.pps_prev,name); + if (ret!=-1) + return ret; + } + if (stde.pps_next != -1) { + ret=STORAGE_look_for_named_pps(hf,stde.pps_next,name); + if (ret!=-1) + return ret; + } + return -1; +} + +/****************************************************************************** + * STORAGE_dump_pps_entry [Internal] + * + * FIXME + * Function is unused + */ +void +STORAGE_dump_pps_entry(struct storage_pps_entry *stde) { +#if 0 + char name[33]; + + WideCharToMultiByte( CP_ACP, 0, stde->pps_rawname, -1, name, sizeof(name), NULL, NULL); + if (!stde->pps_sizeofname) + return; + Print(MAX_TRACE, ("name: %s\n",name)); + Print(MAX_TRACE, ("type: %d\n",stde->pps_type)); + Print(MAX_TRACE, ("prev pps: %ld\n",stde->pps_prev)); + Print(MAX_TRACE, ("next pps: %ld\n",stde->pps_next)); + Print(MAX_TRACE, ("dir pps: %ld\n",stde->pps_dir)); + Print(MAX_TRACE, ("guid: %s\n",PRINT_GUID(&(stde->pps_guid)))); + if (stde->pps_type !=2) { + time_t t; + DWORD dw; + RtlTimeToSecondsSince1970(&(stde->pps_ft1),&dw); + t = dw; + Print(MAX_TRACE, ("ts1: %s\n",ctime(&t))); + RtlTimeToSecondsSince1970(&(stde->pps_ft2),&dw); + t = dw; + Print(MAX_TRACE, ("ts2: %s\n",ctime(&t))); + } + Print(MAX_TRACE, ("startblock: %ld\n",stde->pps_sb)); + Print(MAX_TRACE, ("size: %ld\n",stde->pps_size)); +#endif +} + +/****************************************************************************** + * STORAGE_init_storage [INTERNAL] + */ +static BOOL +STORAGE_init_storage(HFILE hf) { + BYTE block[BIGSIZE]; + LPDWORD bbs; + struct storage_header *sth; + struct storage_pps_entry *stde; + + assert(-1!=_llseek(hf,0,SEEK_SET)); + /* block -1 is the storage header */ + sth = (struct storage_header*)block; + memcpy(sth->magic,STORAGE_magic,8); + memset(sth->unknown1,0,sizeof(sth->unknown1)); + memset(sth->unknown2,0,sizeof(sth->unknown2)); + memset(sth->unknown3,0,sizeof(sth->unknown3)); + sth->num_of_bbd_blocks = 1; + sth->root_startblock = 1; + sth->sbd_startblock = 0xffffffff; + memset(sth->bbd_list,0xff,sizeof(sth->bbd_list)); + sth->bbd_list[0] = 0; + assert(BIGSIZE==_lwrite(hf,block,BIGSIZE)); + /* block 0 is the big block directory */ + bbs=(LPDWORD)block; + memset(block,0xff,sizeof(block)); /* mark all blocks as free */ + bbs[0]=STORAGE_CHAINENTRY_ENDOFCHAIN; /* for this block */ + bbs[1]=STORAGE_CHAINENTRY_ENDOFCHAIN; /* for directory entry */ + assert(BIGSIZE==_lwrite(hf,block,BIGSIZE)); + /* block 1 is the root directory entry */ + memset(block,0x00,sizeof(block)); + stde = (struct storage_pps_entry*)block; + MultiByteToWideChar( CP_ACP, 0, "RootEntry", -1, stde->pps_rawname, + sizeof(stde->pps_rawname)/sizeof(WCHAR)); + stde->pps_sizeofname = (lstrlenW(stde->pps_rawname)+1) * sizeof(WCHAR); + stde->pps_type = 5; + stde->pps_dir = -1; + stde->pps_next = -1; + stde->pps_prev = -1; + stde->pps_sb = 0xffffffff; + stde->pps_size = 0; + assert(BIGSIZE==_lwrite(hf,block,BIGSIZE)); + return TRUE; +} + +/****************************************************************************** + * STORAGE_set_big_chain [Internal] + */ +static BOOL +STORAGE_set_big_chain(HFILE hf,int blocknr,INT type) { + BYTE block[BIGSIZE]; + LPINT bbd = (LPINT)block; + int nextblocknr,bigblocknr; + struct storage_header sth; + + READ_HEADER; + assert(blocknr!=type); + while (blocknr>=0) { + bigblocknr = sth.bbd_list[blocknr/128]; + assert(bigblocknr>=0); + assert(STORAGE_get_big_block(hf,bigblocknr,block)); + + nextblocknr = bbd[blocknr&(128-1)]; + bbd[blocknr&(128-1)] = type; + if (type>=0) + return TRUE; + assert(STORAGE_put_big_block(hf,bigblocknr,block)); + type = STORAGE_CHAINENTRY_FREE; + blocknr = nextblocknr; + } + return TRUE; +} + +/****************************************************************************** + * STORAGE_set_small_chain [Internal] + */ +static BOOL +STORAGE_set_small_chain(HFILE hf,int blocknr,INT type) { + BYTE block[BIGSIZE]; + LPINT sbd = (LPINT)block; + int lastblocknr,nextsmallblocknr,bigblocknr; + struct storage_header sth; + + READ_HEADER; + + assert(blocknr!=type); + lastblocknr=-129;bigblocknr=-2; + while (blocknr>=0) { + /* cache block ... */ + if (lastblocknr/128!=blocknr/128) { + bigblocknr = STORAGE_get_nth_next_big_blocknr(hf,sth.sbd_startblock,blocknr/128); + assert(bigblocknr>=0); + assert(STORAGE_get_big_block(hf,bigblocknr,block)); + } + lastblocknr = blocknr; + nextsmallblocknr = sbd[blocknr&(128-1)]; + sbd[blocknr&(128-1)] = type; + assert(STORAGE_put_big_block(hf,bigblocknr,block)); + if (type>=0) + return TRUE; + type = STORAGE_CHAINENTRY_FREE; + blocknr = nextsmallblocknr; + } + return TRUE; +} + +/****************************************************************************** + * STORAGE_get_free_big_blocknr [Internal] + */ +static int +STORAGE_get_free_big_blocknr(HFILE hf) { + BYTE block[BIGSIZE]; + LPINT sbd = (LPINT)block; + int lastbigblocknr,i,curblock,bigblocknr; + struct storage_header sth; + + READ_HEADER; + curblock = 0; + lastbigblocknr = -1; + bigblocknr = sth.bbd_list[curblock]; + while (curblock=0); + assert(STORAGE_get_big_block(hf,bigblocknr,block)); + for (i=0;i<128;i++) + if (sbd[i]==STORAGE_CHAINENTRY_FREE) { + sbd[i] = STORAGE_CHAINENTRY_ENDOFCHAIN; + assert(STORAGE_put_big_block(hf,bigblocknr,block)); + memset(block,0x42,sizeof(block)); + assert(STORAGE_put_big_block(hf,i+curblock*128,block)); + return i+curblock*128; + } + lastbigblocknr = bigblocknr; + bigblocknr = sth.bbd_list[++curblock]; + } + bigblocknr = curblock*128; + /* since we have marked all blocks from 0 up to curblock*128-1 + * the next free one is curblock*128, where we happily put our + * next large block depot. + */ + memset(block,0xff,sizeof(block)); + /* mark the block allocated and returned by this function */ + sbd[1] = STORAGE_CHAINENTRY_ENDOFCHAIN; + assert(STORAGE_put_big_block(hf,bigblocknr,block)); + + /* if we had a bbd block already (mostlikely) we need + * to link the new one into the chain + */ + if (lastbigblocknr!=-1) + assert(STORAGE_set_big_chain(hf,lastbigblocknr,bigblocknr)); + sth.bbd_list[curblock]=bigblocknr; + sth.num_of_bbd_blocks++; + assert(sth.num_of_bbd_blocks==curblock+1); + assert(STORAGE_put_big_block(hf,-1,(LPBYTE)&sth)); + + /* Set the end of the chain for the bigblockdepots */ + assert(STORAGE_set_big_chain(hf,bigblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN)); + /* add 1, for the first entry is used for the additional big block + * depot. (means we already used bigblocknr) */ + memset(block,0x42,sizeof(block)); + /* allocate this block (filled with 0x42) */ + assert(STORAGE_put_big_block(hf,bigblocknr+1,block)); + return bigblocknr+1; } -WINOLEAPI StgOpenStorage(IN const OLECHAR FAR* pwcsName, - IN IStorage FAR *pstgPriority, - IN DWORD grfMode, - IN SNB snbExclude, - IN DWORD reserved, - OUT IStorage FAR * FAR *ppstgOpen) -{ - return S_OK; +/****************************************************************************** + * STORAGE_get_free_small_blocknr [Internal] + */ +static int +STORAGE_get_free_small_blocknr(HFILE hf) { + BYTE block[BIGSIZE]; + LPINT sbd = (LPINT)block; + int lastbigblocknr,newblocknr,i,curblock,bigblocknr; + struct storage_pps_entry root; + struct storage_header sth; + + READ_HEADER; + bigblocknr = sth.sbd_startblock; + curblock = 0; + lastbigblocknr = -1; + newblocknr = -1; + while (bigblocknr>=0) { + if (!STORAGE_get_big_block(hf,bigblocknr,block)) + return -1; + for (i=0;i<128;i++) + if (sbd[i]==STORAGE_CHAINENTRY_FREE) { + sbd[i]=STORAGE_CHAINENTRY_ENDOFCHAIN; + newblocknr = i+curblock*128; + break; + } + if (i!=128) + break; + lastbigblocknr = bigblocknr; + bigblocknr = STORAGE_get_next_big_blocknr(hf,bigblocknr); + curblock++; + } + if (newblocknr==-1) { + bigblocknr = STORAGE_get_free_big_blocknr(hf); + if (bigblocknr<0) + return -1; + READ_HEADER; + memset(block,0xff,sizeof(block)); + sbd[0]=STORAGE_CHAINENTRY_ENDOFCHAIN; + if (!STORAGE_put_big_block(hf,bigblocknr,block)) + return -1; + if (lastbigblocknr==-1) { + sth.sbd_startblock = bigblocknr; + if (!STORAGE_put_big_block(hf,-1,(LPBYTE)&sth)) /* need to write it */ + return -1; + } else { + if (!STORAGE_set_big_chain(hf,lastbigblocknr,bigblocknr)) + return -1; + } + if (!STORAGE_set_big_chain(hf,bigblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN)) + return -1; + newblocknr = curblock*128; + } + /* allocate enough big blocks for storing the allocated small block */ + if (!STORAGE_get_root_pps_entry(hf,&root)) + return -1; + if (root.pps_sb==-1) + lastbigblocknr = -1; + else + lastbigblocknr = STORAGE_get_nth_next_big_blocknr(hf,root.pps_sb,(root.pps_size-1)/BIGSIZE); + while (root.pps_size < (newblocknr*SMALLSIZE+SMALLSIZE-1)) { + /* we need to allocate more stuff */ + bigblocknr = STORAGE_get_free_big_blocknr(hf); + if (bigblocknr<0) + return -1; + READ_HEADER; + if (root.pps_sb==-1) { + root.pps_sb = bigblocknr; + root.pps_size += BIGSIZE; + } else { + if (!STORAGE_set_big_chain(hf,lastbigblocknr,bigblocknr)) + return -1; + root.pps_size += BIGSIZE; + } + lastbigblocknr = bigblocknr; + } + if (!STORAGE_set_big_chain(hf,lastbigblocknr,STORAGE_CHAINENTRY_ENDOFCHAIN)) + return -1; + if (!STORAGE_put_pps_entry(hf,0,&root)) + return -1; + return newblocknr; } -WINOLEAPI StgOpenStorageOnILockBytes(IN ILockBytes FAR *plkbyt, - IN IStorage FAR *pstgPriority, - IN DWORD grfMode, - IN SNB snbExclude, - IN DWORD reserved, - OUT IStorage FAR * FAR *ppstgOpen) +/****************************************************************************** + * STORAGE_get_free_pps_entry [Internal] + */ +static int +STORAGE_get_free_pps_entry(HFILE hf) { + int blocknr,i,curblock,lastblocknr; + BYTE block[BIGSIZE]; + struct storage_pps_entry *stde = (struct storage_pps_entry*)block; + struct storage_header sth; + + READ_HEADER; + blocknr = sth.root_startblock; + assert(blocknr>=0); + curblock=0; + while (blocknr>=0) { + if (!STORAGE_get_big_block(hf,blocknr,block)) + return -1; + for (i=0;i<4;i++) + if (stde[i].pps_sizeofname==0) /* free */ + return curblock*4+i; + lastblocknr = blocknr; + blocknr = STORAGE_get_next_big_blocknr(hf,blocknr); + curblock++; + } + assert(blocknr==STORAGE_CHAINENTRY_ENDOFCHAIN); + blocknr = STORAGE_get_free_big_blocknr(hf); + /* sth invalidated */ + if (blocknr<0) + return -1; + + if (!STORAGE_set_big_chain(hf,lastblocknr,blocknr)) + return -1; + if (!STORAGE_set_big_chain(hf,blocknr,STORAGE_CHAINENTRY_ENDOFCHAIN)) + return -1; + memset(block,0,sizeof(block)); + STORAGE_put_big_block(hf,blocknr,block); + return curblock*4; +} + +/* --- IStream32 implementation */ + +typedef struct { - return S_OK; + /* IUnknown fields */ + ICOM_VFIELD(IStream); + DWORD ref; + /* IStream32 fields */ + struct storage_pps_entry stde; + int ppsent; + HFILE hf; + ULARGE_INTEGER offset; +} IStream32Impl; + +/***************************************************************************** + * IStream32_QueryInterface [VTABLE] + */ +HRESULT WINAPI IStream_fnQueryInterface( + IStream* iface,REFIID refiid,LPVOID *obj +) { + ICOM_THIS(IStream32Impl,iface); + + Print(MAX_TRACE, ("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj)); + if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) { + *obj = This; + return 0; + } + return OLE_E_ENUM_NOMORE; + +} + +/****************************************************************************** + * IStream32_AddRef [VTABLE] + */ +ULONG WINAPI IStream_fnAddRef(IStream* iface) { + ICOM_THIS(IStream32Impl,iface); + return ++(This->ref); +} + +/****************************************************************************** + * IStream32_Release [VTABLE] + */ +ULONG WINAPI IStream_fnRelease(IStream* iface) { +#if 0 + ICOM_THIS(IStream32Impl,iface); + FlushFileBuffers(This->hf); + This->ref--; + if (!This->ref) { + CloseHandle(This->hf); + SEGPTR_FREE(This); + return 0; + } + return This->ref; +#else + UNIMPLEMENTED; + return 0; +#endif } -WINOLEAPI StgIsStorageFile(IN const OLECHAR FAR* pwcsName) -{ - return S_OK; +/****************************************************************************** + * Storage API functions + */ + +/****************************************************************************** + * StgCreateDocFile16 [STORAGE.1] + */ +HRESULT WINAPI StgCreateDocFile16( + LPCOLESTR16 pwcsName,DWORD grfMode,DWORD reserved,IStorage16 **ppstgOpen +) { + UNIMPLEMENTED; + return S_OK; } -WINOLEAPI StgIsStorageILockBytes(IN ILockBytes FAR* plkbyt) +/****************************************************************************** + * StgIsStorageFile16 [STORAGE.5] + */ +HRESULT WINAPI StgIsStorageFile16(LPCOLESTR16 fn) { + UNIMPLEMENTED; + return S_OK; +} + +/****************************************************************************** + * StgIsStorageFile [OLE32.146] + */ +HRESULT WINAPI +StgIsStorageFile(LPCOLESTR fn) { - return S_OK; +#if 0 + LPOLESTR16 xfn = HEAP_strdupWtoA(GetProcessHeap(),0,fn); + HRESULT ret = StgIsStorageFile16(xfn); + + HeapFree(GetProcessHeap(),0,xfn); + return ret; +#else + UNIMPLEMENTED; + return S_OK; +#endif } -WINOLEAPI StgSetTimes(IN OLECHAR const FAR* lpszName, - IN FILETIME const FAR* pctime, - IN FILETIME const FAR* patime, - IN FILETIME const FAR* pmtime); - -WINOLEAPI StgOpenAsyncDocfileOnIFillLockBytes( IN IFillLockBytes *pflb, - IN DWORD grfMode, - IN DWORD asyncFlags, - OUT IStorage **ppstgOpen) -{ - return S_OK; +/****************************************************************************** + * StgOpenStorage16 [STORAGE.3] + */ +HRESULT WINAPI StgOpenStorage16( + LPCOLESTR16 pwcsName,IStorage16 *pstgPriority,DWORD grfMode, + SNB16 snbExclude,DWORD reserved, IStorage16 **ppstgOpen +) { + UNIMPLEMENTED; + return S_OK; } -WINOLEAPI StgGetIFillLockBytesOnILockBytes( IN ILockBytes *pilb, - OUT IFillLockBytes **ppflb) -{ - return S_OK; -} - - -WINOLEAPI StgGetIFillLockBytesOnFile(IN OLECHAR const *pwcsName, - OUT IFillLockBytes **ppflb) -{ - return S_OK; -} - - - -WINOLEAPI StgOpenLayoutDocfile(IN OLECHAR const *pwcsDfName, - IN DWORD grfMode, - IN DWORD reserved, - OUT IStorage **ppstgOpen) -{ - return S_OK; -} - - -WINOLEAPI StgCreateStorageEx (IN const WCHAR* pwcsName, - IN DWORD grfMode, - IN DWORD stgfmt, // enum - IN DWORD grfAttrs, // reserved - IN STGOPTIONS * pStgOptions, - IN void * reserved, - IN REFIID riid, - OUT void ** ppObjectOpen) -{ - return S_OK; -} - - -WINOLEAPI StgOpenStorageEx (IN const WCHAR* pwcsName, - IN DWORD grfMode, - IN DWORD stgfmt, // enum - IN DWORD grfAttrs, // reserved - IN STGOPTIONS * pStgOptions, - IN void * reserved, - IN REFIID riid, - OUT void ** ppObjectOpen) -{ - return S_OK; -}*/ diff --git a/reactos/lib/ole32/storage32.c b/reactos/lib/ole32/storage32.c new file mode 100644 index 00000000000..80987cd849e --- /dev/null +++ b/reactos/lib/ole32/storage32.c @@ -0,0 +1,6989 @@ +/* + * Compound Storage (32 bit version) + * Storage implementation + * + * This file contains the compound file implementation + * of the storage interface. + * + * Copyright 1999 Francis Beaudet + * Copyright 1999 Sylvain St-Germain + * Copyright 1999 Thuy Nguyen + */ + +#include +#include +#include + +#include +#include +#include + +#include + +#if 1 + +/* From wingdi16.h of WINE */ + +typedef HANDLE HMETAFILE16; + +typedef struct +{ + INT16 mm; + INT16 xExt; + INT16 yExt; + HMETAFILE16 hMF; +} METAFILEPICT16, *LPMETAFILEPICT16; + +#endif + +/* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ +#define OLESTREAM_ID 0x501 +#define OLESTREAM_MAX_STR_LEN 255 + +static const char rootPropertyName[] = "Root Entry"; + + +/* OLESTREAM memory structure to use for Get and Put Routines */ +/* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ +typedef struct +{ + DWORD dwOleID; + DWORD dwTypeID; + DWORD dwOleTypeNameLength; + CHAR strOleTypeName[OLESTREAM_MAX_STR_LEN]; + CHAR *pstrOleObjFileName; + DWORD dwOleObjFileNameLength; + DWORD dwMetaFileWidth; + DWORD dwMetaFileHeight; + CHAR strUnknown[8]; /* don't know what is this 8 byts information in OLE stream. */ + DWORD dwDataLength; + BYTE *pData; +}OLECONVERT_OLESTREAM_DATA; + +/* CompObj Stream structure */ +/* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ +typedef struct +{ + BYTE byUnknown1[12]; + CLSID clsid; + DWORD dwCLSIDNameLength; + CHAR strCLSIDName[OLESTREAM_MAX_STR_LEN]; + DWORD dwOleTypeNameLength; + CHAR strOleTypeName[OLESTREAM_MAX_STR_LEN]; + DWORD dwProgIDNameLength; + CHAR strProgIDName[OLESTREAM_MAX_STR_LEN]; + BYTE byUnknown2[16]; +}OLECONVERT_ISTORAGE_COMPOBJ; + + +/* Ole Presention Stream structure */ +/* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ +typedef struct +{ + BYTE byUnknown1[28]; + DWORD dwExtentX; + DWORD dwExtentY; + DWORD dwSize; + BYTE *pData; +}OLECONVERT_ISTORAGE_OLEPRES; + + + +/*********************************************************************** + * Forward declaration of internal functions used by the method DestroyElement + */ +static HRESULT deleteStorageProperty( + StorageImpl *parentStorage, + ULONG foundPropertyIndexToDelete, + StgProperty propertyToDelete); + +static HRESULT deleteStreamProperty( + StorageImpl *parentStorage, + ULONG foundPropertyIndexToDelete, + StgProperty propertyToDelete); + +static HRESULT findPlaceholder( + StorageImpl *storage, + ULONG propertyIndexToStore, + ULONG storagePropertyIndex, + INT typeOfRelation); + +static HRESULT adjustPropertyChain( + StorageImpl *This, + StgProperty propertyToDelete, + StgProperty parentProperty, + ULONG parentPropertyId, + INT typeOfRelation); + +/*********************************************************************** + * Declaration of the functions used to manipulate StgProperty + */ + +static ULONG getFreeProperty( + StorageImpl *storage); + +static void updatePropertyChain( + StorageImpl *storage, + ULONG newPropertyIndex, + StgProperty newProperty); + +static LONG propertyNameCmp( + OLECHAR *newProperty, + OLECHAR *currentProperty); + + +/*********************************************************************** + * Declaration of miscellaneous functions... + */ +static HRESULT validateSTGM(DWORD stgmValue); + +static DWORD GetShareModeFromSTGM(DWORD stgm); +static DWORD GetAccessModeFromSTGM(DWORD stgm); +static DWORD GetCreationModeFromSTGM(DWORD stgm); + +/* + * Virtual function table for the IStorage32Impl class. + */ +static ICOM_VTABLE(IStorage) Storage32Impl_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + StorageBaseImpl_QueryInterface, + StorageBaseImpl_AddRef, + StorageBaseImpl_Release, + StorageBaseImpl_CreateStream, + StorageBaseImpl_OpenStream, + StorageImpl_CreateStorage, + StorageBaseImpl_OpenStorage, + StorageImpl_CopyTo, + StorageImpl_MoveElementTo, + StorageImpl_Commit, + StorageImpl_Revert, + StorageBaseImpl_EnumElements, + StorageImpl_DestroyElement, + StorageBaseImpl_RenameElement, + StorageImpl_SetElementTimes, + StorageBaseImpl_SetClass, + StorageImpl_SetStateBits, + StorageBaseImpl_Stat +}; + +/* + * Virtual function table for the Storage32InternalImpl class. + */ +static ICOM_VTABLE(IStorage) Storage32InternalImpl_Vtbl = + { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + StorageBaseImpl_QueryInterface, + StorageBaseImpl_AddRef, + StorageBaseImpl_Release, + StorageBaseImpl_CreateStream, + StorageBaseImpl_OpenStream, + StorageImpl_CreateStorage, + StorageBaseImpl_OpenStorage, + StorageImpl_CopyTo, + StorageImpl_MoveElementTo, + StorageInternalImpl_Commit, + StorageInternalImpl_Revert, + StorageBaseImpl_EnumElements, + StorageImpl_DestroyElement, + StorageBaseImpl_RenameElement, + StorageImpl_SetElementTimes, + StorageBaseImpl_SetClass, + StorageImpl_SetStateBits, + StorageBaseImpl_Stat +}; + +/* + * Virtual function table for the IEnumSTATSTGImpl class. + */ +static ICOM_VTABLE(IEnumSTATSTG) IEnumSTATSTGImpl_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IEnumSTATSTGImpl_QueryInterface, + IEnumSTATSTGImpl_AddRef, + IEnumSTATSTGImpl_Release, + IEnumSTATSTGImpl_Next, + IEnumSTATSTGImpl_Skip, + IEnumSTATSTGImpl_Reset, + IEnumSTATSTGImpl_Clone +}; + + + + + +/************************************************************************ +** Storage32BaseImpl implementatiion +*/ + +/************************************************************************ + * Storage32BaseImpl_QueryInterface (IUnknown) + * + * This method implements the common QueryInterface for all IStorage32 + * implementations contained in this file. + * + * See Windows documentation for more details on IUnknown methods. + */ +HRESULT WINAPI StorageBaseImpl_QueryInterface( + IStorage* iface, + REFIID riid, + void** ppvObject) +{ + ICOM_THIS(StorageBaseImpl,iface); + /* + * Perform a sanity check on the parameters. + */ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = (IStorage*)This; + } + else if (memcmp(&IID_IStorage, riid, sizeof(IID_IStorage)) == 0) + { + *ppvObject = (IStorage*)This; + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* + * Query Interface always increases the reference count by one when it is + * successful + */ + StorageBaseImpl_AddRef(iface); + + return S_OK; +} + +/************************************************************************ + * Storage32BaseImpl_AddRef (IUnknown) + * + * This method implements the common AddRef for all IStorage32 + * implementations contained in this file. + * + * See Windows documentation for more details on IUnknown methods. + */ +ULONG WINAPI StorageBaseImpl_AddRef( + IStorage* iface) +{ + ICOM_THIS(StorageBaseImpl,iface); + This->ref++; + + return This->ref; +} + +/************************************************************************ + * Storage32BaseImpl_Release (IUnknown) + * + * This method implements the common Release for all IStorage32 + * implementations contained in this file. + * + * See Windows documentation for more details on IUnknown methods. + */ +ULONG WINAPI StorageBaseImpl_Release( + IStorage* iface) +{ + ICOM_THIS(StorageBaseImpl,iface); + /* + * Decrease the reference count on this object. + */ + This->ref--; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (This->ref==0) + { + /* + * Since we are using a system of base-classes, we want to call the + * destructor of the appropriate derived class. To do this, we are + * using virtual functions to implement the destructor. + */ + This->v_destructor(This); + + return 0; + } + + return This->ref; +} + +/************************************************************************ + * Storage32BaseImpl_OpenStream (IStorage) + * + * This method will open the specified stream object from the current storage. + * + * See Windows documentation for more details on IStorage methods. + */ +HRESULT WINAPI StorageBaseImpl_OpenStream( + IStorage* iface, + const OLECHAR* pwcsName, /* [string][in] */ + void* reserved1, /* [unique][in] */ + DWORD grfMode, /* [in] */ + DWORD reserved2, /* [in] */ + IStream** ppstm) /* [out] */ +{ + ICOM_THIS(StorageBaseImpl,iface); + IEnumSTATSTGImpl* propertyEnumeration; + StgStreamImpl* newStream; + StgProperty currentProperty; + ULONG foundPropertyIndex; + + Print(MAX_TRACE, ("(%p, %S, %p, %lx, %ld, %p)\n", + iface, pwcsName, reserved1, grfMode, reserved2, ppstm)); + + /* + * Perform a sanity check on the parameters. + */ + if ( (pwcsName==NULL) || (ppstm==0) ) + return E_INVALIDARG; + + /* + * Initialize the out parameter + */ + *ppstm = 0; + + /* + * Validate the STGM flags + */ + if ( FAILED( validateSTGM(grfMode) )) + return STG_E_INVALIDFLAG; + + /* + * As documented. + */ + if ( !(grfMode & STGM_SHARE_EXCLUSIVE) || + (grfMode & STGM_DELETEONRELEASE) || + (grfMode & STGM_TRANSACTED) ) + return STG_E_INVALIDFUNCTION; + + /* + * Create a property enumeration to search the properties + */ + propertyEnumeration = IEnumSTATSTGImpl_Construct( + This->ancestorStorage, + This->rootPropertySetIndex); + + /* + * Search the enumeration for the property with the given name + */ + foundPropertyIndex = IEnumSTATSTGImpl_FindProperty( + propertyEnumeration, + pwcsName, + ¤tProperty); + + /* + * Delete the property enumeration since we don't need it anymore + */ + IEnumSTATSTGImpl_Destroy(propertyEnumeration); + + /* + * If it was found, construct the stream object and return a pointer to it. + */ + if ( (foundPropertyIndex!=PROPERTY_NULL) && + (currentProperty.propertyType==PROPTYPE_STREAM) ) + { + newStream = StgStreamImpl_Construct(This, grfMode, foundPropertyIndex); + + if (newStream!=0) + { + newStream->grfMode = grfMode; + *ppstm = (IStream*)newStream; + + /* + * Since we are returning a pointer to the interface, we have to + * nail down the reference. + */ + StgStreamImpl_AddRef(*ppstm); + + return S_OK; + } + + return E_OUTOFMEMORY; + } + + return STG_E_FILENOTFOUND; +} + +/************************************************************************ + * Storage32BaseImpl_OpenStorage (IStorage) + * + * This method will open a new storage object from the current storage. + * + * See Windows documentation for more details on IStorage methods. + */ +HRESULT WINAPI StorageBaseImpl_OpenStorage( + IStorage* iface, + const OLECHAR* pwcsName, /* [string][unique][in] */ + IStorage* pstgPriority, /* [unique][in] */ + DWORD grfMode, /* [in] */ + SNB snbExclude, /* [unique][in] */ + DWORD reserved, /* [in] */ + IStorage** ppstg) /* [out] */ +{ + ICOM_THIS(StorageBaseImpl,iface); + StorageInternalImpl* newStorage; + IEnumSTATSTGImpl* propertyEnumeration; + StgProperty currentProperty; + ULONG foundPropertyIndex; + + Print(MAX_TRACE, ("(%p, %S, %p, %lx, %p, %ld, %p)\n", + iface, pwcsName, pstgPriority, + grfMode, snbExclude, reserved, ppstg)); + + /* + * Perform a sanity check on the parameters. + */ + if ( (This==0) || (pwcsName==NULL) || (ppstg==0) ) + return E_INVALIDARG; + + /* + * Validate the STGM flags + */ + if ( FAILED( validateSTGM(grfMode) )) + return STG_E_INVALIDFLAG; + + /* + * As documented. + */ + if ( !(grfMode & STGM_SHARE_EXCLUSIVE) || + (grfMode & STGM_DELETEONRELEASE) || + (grfMode & STGM_PRIORITY) ) + return STG_E_INVALIDFUNCTION; + + /* + * Initialize the out parameter + */ + *ppstg = 0; + + /* + * Create a property enumeration to search the properties + */ + propertyEnumeration = IEnumSTATSTGImpl_Construct( + This->ancestorStorage, + This->rootPropertySetIndex); + + /* + * Search the enumeration for the property with the given name + */ + foundPropertyIndex = IEnumSTATSTGImpl_FindProperty( + propertyEnumeration, + pwcsName, + ¤tProperty); + + /* + * Delete the property enumeration since we don't need it anymore + */ + IEnumSTATSTGImpl_Destroy(propertyEnumeration); + + /* + * If it was found, construct the stream object and return a pointer to it. + */ + if ( (foundPropertyIndex!=PROPERTY_NULL) && + (currentProperty.propertyType==PROPTYPE_STORAGE) ) + { + /* + * Construct a new Storage object + */ + newStorage = StorageInternalImpl_Construct( + This->ancestorStorage, + foundPropertyIndex); + + if (newStorage != 0) + { + *ppstg = (IStorage*)newStorage; + + /* + * Since we are returning a pointer to the interface, + * we have to nail down the reference. + */ + StorageBaseImpl_AddRef(*ppstg); + + return S_OK; + } + + return STG_E_INSUFFICIENTMEMORY; + } + + return STG_E_FILENOTFOUND; +} + +/************************************************************************ + * Storage32BaseImpl_EnumElements (IStorage) + * + * This method will create an enumerator object that can be used to + * retrieve informatino about all the properties in the storage object. + * + * See Windows documentation for more details on IStorage methods. + */ +HRESULT WINAPI StorageBaseImpl_EnumElements( + IStorage* iface, + DWORD reserved1, /* [in] */ + void* reserved2, /* [size_is][unique][in] */ + DWORD reserved3, /* [in] */ + IEnumSTATSTG** ppenum) /* [out] */ +{ + ICOM_THIS(StorageBaseImpl,iface); + IEnumSTATSTGImpl* newEnum; + + Print(MAX_TRACE, ("(%p, %ld, %p, %ld, %p)\n", + iface, reserved1, reserved2, reserved3, ppenum)); + + /* + * Perform a sanity check on the parameters. + */ + if ( (This==0) || (ppenum==0)) + return E_INVALIDARG; + + /* + * Construct the enumerator. + */ + newEnum = IEnumSTATSTGImpl_Construct( + This->ancestorStorage, + This->rootPropertySetIndex); + + if (newEnum!=0) + { + *ppenum = (IEnumSTATSTG*)newEnum; + + /* + * Don't forget to nail down a reference to the new object before + * returning it. + */ + IEnumSTATSTGImpl_AddRef(*ppenum); + + return S_OK; + } + + return E_OUTOFMEMORY; +} + +/************************************************************************ + * Storage32BaseImpl_Stat (IStorage) + * + * This method will retrieve information about this storage object. + * + * See Windows documentation for more details on IStorage methods. + */ +HRESULT WINAPI StorageBaseImpl_Stat( + IStorage* iface, + STATSTG* pstatstg, /* [out] */ + DWORD grfStatFlag) /* [in] */ +{ + ICOM_THIS(StorageBaseImpl,iface); + StgProperty curProperty; + BOOL readSuccessful; + + Print(MAX_TRACE, ("(%p, %p, %lx)\n", + iface, pstatstg, grfStatFlag)); + + /* + * Perform a sanity check on the parameters. + */ + if ( (This==0) || (pstatstg==0)) + return E_INVALIDARG; + + /* + * Read the information from the property. + */ + readSuccessful = StorageImpl_ReadProperty( + This->ancestorStorage, + This->rootPropertySetIndex, + &curProperty); + + if (readSuccessful) + { + StorageUtl_CopyPropertyToSTATSTG( + pstatstg, + &curProperty, + grfStatFlag); + + return S_OK; + } + + return E_FAIL; +} + +/************************************************************************ + * Storage32BaseImpl_RenameElement (IStorage) + * + * This method will rename the specified element. + * + * See Windows documentation for more details on IStorage methods. + * + * Implementation notes: The method used to rename consists of creating a clone + * of the deleted StgProperty object setting it with the new name and to + * perform a DestroyElement of the old StgProperty. + */ +HRESULT WINAPI StorageBaseImpl_RenameElement( + IStorage* iface, + const OLECHAR* pwcsOldName, /* [in] */ + const OLECHAR* pwcsNewName) /* [in] */ +{ + ICOM_THIS(StorageBaseImpl,iface); + IEnumSTATSTGImpl* propertyEnumeration; + StgProperty currentProperty; + ULONG foundPropertyIndex; + + Print(MAX_TRACE, ("(%p, %S, %S)\n", + iface, pwcsOldName, pwcsNewName)); + + /* + * Create a property enumeration to search the properties + */ + propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage, + This->rootPropertySetIndex); + + /* + * Search the enumeration for the new property name + */ + foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, + pwcsNewName, + ¤tProperty); + + if (foundPropertyIndex != PROPERTY_NULL) + { + /* + * There is already a property with the new name + */ + IEnumSTATSTGImpl_Destroy(propertyEnumeration); + return STG_E_FILEALREADYEXISTS; + } + + IEnumSTATSTGImpl_Reset((IEnumSTATSTG*)propertyEnumeration); + + /* + * Search the enumeration for the old property name + */ + foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, + pwcsOldName, + ¤tProperty); + + /* + * Delete the property enumeration since we don't need it anymore + */ + IEnumSTATSTGImpl_Destroy(propertyEnumeration); + + if (foundPropertyIndex != PROPERTY_NULL) + { + StgProperty renamedProperty; + ULONG renamedPropertyIndex; + + /* + * Setup a new property for the renamed property + */ + renamedProperty.sizeOfNameString = + ( lstrlenW(pwcsNewName)+1 ) * sizeof(WCHAR); + + if (renamedProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN) + return STG_E_INVALIDNAME; + + lstrcpyW(renamedProperty.name, pwcsNewName); + + renamedProperty.propertyType = currentProperty.propertyType; + renamedProperty.startingBlock = currentProperty.startingBlock; + renamedProperty.size.u.LowPart = currentProperty.size.u.LowPart; + renamedProperty.size.u.HighPart = currentProperty.size.u.HighPart; + + renamedProperty.previousProperty = PROPERTY_NULL; + renamedProperty.nextProperty = PROPERTY_NULL; + + /* + * Bring the dirProperty link in case it is a storage and in which + * case the renamed storage elements don't require to be reorganized. + */ + renamedProperty.dirProperty = currentProperty.dirProperty; + + /* call CoFileTime to get the current time + renamedProperty.timeStampS1 + renamedProperty.timeStampD1 + renamedProperty.timeStampS2 + renamedProperty.timeStampD2 + renamedProperty.propertyUniqueID + */ + + /* + * Obtain a free property in the property chain + */ + renamedPropertyIndex = getFreeProperty(This->ancestorStorage); + + /* + * Save the new property into the new property spot + */ + StorageImpl_WriteProperty( + This->ancestorStorage, + renamedPropertyIndex, + &renamedProperty); + + /* + * Find a spot in the property chain for our newly created property. + */ + updatePropertyChain( + (StorageImpl*)This, + renamedPropertyIndex, + renamedProperty); + + /* + * At this point the renamed property has been inserted in the tree, + * now, before to Destroy the old property we must zeroed it's dirProperty + * otherwise the DestroyProperty below will zap it all and we do not want + * this to happen. + * Also, we fake that the old property is a storage so the DestroyProperty + * will not do a SetSize(0) on the stream data. + * + * This means that we need to tweek the StgProperty if it is a stream or a + * non empty storage. + */ + StorageImpl_ReadProperty(This->ancestorStorage, + foundPropertyIndex, + ¤tProperty); + + currentProperty.dirProperty = PROPERTY_NULL; + currentProperty.propertyType = PROPTYPE_STORAGE; + StorageImpl_WriteProperty( + This->ancestorStorage, + foundPropertyIndex, + ¤tProperty); + + /* + * Invoke Destroy to get rid of the ole property and automatically redo + * the linking of it's previous and next members... + */ + StorageImpl_DestroyElement((IStorage*)This->ancestorStorage, pwcsOldName); + + } + else + { + /* + * There is no property with the old name + */ + return STG_E_FILENOTFOUND; + } + + return S_OK; +} + +/************************************************************************ + * Storage32BaseImpl_CreateStream (IStorage) + * + * This method will create a stream object within this storage + * + * See Windows documentation for more details on IStorage methods. + */ +HRESULT WINAPI StorageBaseImpl_CreateStream( + IStorage* iface, + const OLECHAR* pwcsName, /* [string][in] */ + DWORD grfMode, /* [in] */ + DWORD reserved1, /* [in] */ + DWORD reserved2, /* [in] */ + IStream** ppstm) /* [out] */ +{ + ICOM_THIS(StorageBaseImpl,iface); + IEnumSTATSTGImpl* propertyEnumeration; + StgStreamImpl* newStream; + StgProperty currentProperty, newStreamProperty; + ULONG foundPropertyIndex, newPropertyIndex; + + Print(MAX_TRACE, ("(%p, %S, %lx, %ld, %ld, %p)\n", + iface, pwcsName, grfMode, + reserved1, reserved2, ppstm)); + + /* + * Validate parameters + */ + if (ppstm == 0) + return STG_E_INVALIDPOINTER; + + if (pwcsName == 0) + return STG_E_INVALIDNAME; + + /* + * Validate the STGM flags + */ + if ( FAILED( validateSTGM(grfMode) )) + return STG_E_INVALIDFLAG; + + /* + * As documented. + */ + if ( !(grfMode & STGM_SHARE_EXCLUSIVE) || + (grfMode & STGM_DELETEONRELEASE) || + (grfMode & STGM_TRANSACTED) ) + return STG_E_INVALIDFUNCTION; + + /* + * Initialize the out parameter + */ + *ppstm = 0; + + /* + * Create a property enumeration to search the properties + */ + propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage, + This->rootPropertySetIndex); + + foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, + pwcsName, + ¤tProperty); + + IEnumSTATSTGImpl_Destroy(propertyEnumeration); + + if (foundPropertyIndex != PROPERTY_NULL) + { + /* + * An element with this name already exists + */ + if (grfMode & STGM_CREATE) + { + IStorage_DestroyElement(iface, pwcsName); + } + else + return STG_E_FILEALREADYEXISTS; + } + + /* + * memset the empty property + */ + memset(&newStreamProperty, 0, sizeof(StgProperty)); + + newStreamProperty.sizeOfNameString = + ( lstrlenW(pwcsName)+1 ) * sizeof(WCHAR); + + if (newStreamProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN) + return STG_E_INVALIDNAME; + + lstrcpyW(newStreamProperty.name, pwcsName); + + newStreamProperty.propertyType = PROPTYPE_STREAM; + newStreamProperty.startingBlock = BLOCK_END_OF_CHAIN; + newStreamProperty.size.u.LowPart = 0; + newStreamProperty.size.u.HighPart = 0; + + newStreamProperty.previousProperty = PROPERTY_NULL; + newStreamProperty.nextProperty = PROPERTY_NULL; + newStreamProperty.dirProperty = PROPERTY_NULL; + + /* call CoFileTime to get the current time + newStreamProperty.timeStampS1 + newStreamProperty.timeStampD1 + newStreamProperty.timeStampS2 + newStreamProperty.timeStampD2 + */ + + /* newStreamProperty.propertyUniqueID */ + + /* + * Get a free property or create a new one + */ + newPropertyIndex = getFreeProperty(This->ancestorStorage); + + /* + * Save the new property into the new property spot + */ + StorageImpl_WriteProperty( + This->ancestorStorage, + newPropertyIndex, + &newStreamProperty); + + /* + * Find a spot in the property chain for our newly created property. + */ + updatePropertyChain( + (StorageImpl*)This, + newPropertyIndex, + newStreamProperty); + + /* + * Open the stream to return it. + */ + newStream = StgStreamImpl_Construct(This, grfMode, newPropertyIndex); + + if (newStream != 0) + { + *ppstm = (IStream*)newStream; + + /* + * Since we are returning a pointer to the interface, we have to nail down + * the reference. + */ + StgStreamImpl_AddRef(*ppstm); + } + else + { + return STG_E_INSUFFICIENTMEMORY; + } + + return S_OK; +} + +/************************************************************************ + * Storage32BaseImpl_SetClass (IStorage) + * + * This method will write the specified CLSID in the property of this + * storage. + * + * See Windows documentation for more details on IStorage methods. + */ +HRESULT WINAPI StorageBaseImpl_SetClass( + IStorage* iface, + REFCLSID clsid) /* [in] */ +{ + ICOM_THIS(StorageBaseImpl,iface); + HRESULT hRes = E_FAIL; + StgProperty curProperty; + BOOL success; + + Print(MAX_TRACE, ("(%p, %p)\n", iface, clsid)); + + success = StorageImpl_ReadProperty(This->ancestorStorage, + This->rootPropertySetIndex, + &curProperty); + if (success) + { + curProperty.propertyUniqueID = *clsid; + + success = StorageImpl_WriteProperty(This->ancestorStorage, + This->rootPropertySetIndex, + &curProperty); + if (success) + hRes = S_OK; + } + + return hRes; +} + +/************************************************************************ +** Storage32Impl implementation +*/ + +/************************************************************************ + * Storage32Impl_CreateStorage (IStorage) + * + * This method will create the storage object within the provided storage. + * + * See Windows documentation for more details on IStorage methods. + */ +HRESULT WINAPI StorageImpl_CreateStorage( + IStorage* iface, + const OLECHAR *pwcsName, /* [string][in] */ + DWORD grfMode, /* [in] */ + DWORD reserved1, /* [in] */ + DWORD reserved2, /* [in] */ + IStorage **ppstg) /* [out] */ +{ + StorageImpl* const This=(StorageImpl*)iface; + + IEnumSTATSTGImpl *propertyEnumeration; + StgProperty currentProperty; + StgProperty newProperty; + ULONG foundPropertyIndex; + ULONG newPropertyIndex; + HRESULT hr; + + Print(MAX_TRACE, ("(%p, %S, %lx, %ld, %ld, %p)\n", + iface, pwcsName, grfMode, + reserved1, reserved2, ppstg)); + + /* + * Validate parameters + */ + if (ppstg == 0) + return STG_E_INVALIDPOINTER; + + if (pwcsName == 0) + return STG_E_INVALIDNAME; + + /* + * Validate the STGM flags + */ + if ( FAILED( validateSTGM(grfMode) ) || + (grfMode & STGM_DELETEONRELEASE) ) + return STG_E_INVALIDFLAG; + + /* + * Initialize the out parameter + */ + *ppstg = 0; + + /* + * Create a property enumeration and search the properties + */ + propertyEnumeration = IEnumSTATSTGImpl_Construct( This->ancestorStorage, + This->rootPropertySetIndex); + + foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration, + pwcsName, + ¤tProperty); + IEnumSTATSTGImpl_Destroy(propertyEnumeration); + + if (foundPropertyIndex != PROPERTY_NULL) + { + /* + * An element with this name already exists + */ + if (grfMode & STGM_CREATE) + IStorage_DestroyElement(iface, pwcsName); + else + return STG_E_FILEALREADYEXISTS; + } + + /* + * memset the empty property + */ + memset(&newProperty, 0, sizeof(StgProperty)); + + newProperty.sizeOfNameString = (lstrlenW(pwcsName)+1)*sizeof(WCHAR); + + if (newProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN) + return STG_E_INVALIDNAME; + + lstrcpyW(newProperty.name, pwcsName); + + newProperty.propertyType = PROPTYPE_STORAGE; + newProperty.startingBlock = BLOCK_END_OF_CHAIN; + newProperty.size.u.LowPart = 0; + newProperty.size.u.HighPart = 0; + + newProperty.previousProperty = PROPERTY_NULL; + newProperty.nextProperty = PROPERTY_NULL; + newProperty.dirProperty = PROPERTY_NULL; + + /* call CoFileTime to get the current time + newProperty.timeStampS1 + newProperty.timeStampD1 + newProperty.timeStampS2 + newProperty.timeStampD2 + */ + + /* newStorageProperty.propertyUniqueID */ + + /* + * Obtain a free property in the property chain + */ + newPropertyIndex = getFreeProperty(This->ancestorStorage); + + /* + * Save the new property into the new property spot + */ + StorageImpl_WriteProperty( + This->ancestorStorage, + newPropertyIndex, + &newProperty); + + /* + * Find a spot in the property chain for our newly created property. + */ + updatePropertyChain( + This, + newPropertyIndex, + newProperty); + + /* + * Open it to get a pointer to return. + */ + hr = IStorage_OpenStorage( + iface, + (OLECHAR*)pwcsName, + 0, + grfMode, + 0, + 0, + ppstg); + + if( (hr != S_OK) || (*ppstg == NULL)) + { + return hr; + } + + + return S_OK; +} + + +/*************************************************************************** + * + * Internal Method + * + * Get a free property or create a new one. + */ +static ULONG getFreeProperty( + StorageImpl *storage) +{ + ULONG currentPropertyIndex = 0; + ULONG newPropertyIndex = PROPERTY_NULL; + BOOL readSuccessful = TRUE; + StgProperty currentProperty; + + do + { + /* + * Start by reading the root property + */ + readSuccessful = StorageImpl_ReadProperty(storage->ancestorStorage, + currentPropertyIndex, + ¤tProperty); + if (readSuccessful) + { + if (currentProperty.sizeOfNameString == 0) + { + /* + * The property existis and is available, we found it. + */ + newPropertyIndex = currentPropertyIndex; + } + } + else + { + /* + * We exhausted the property list, we will create more space below + */ + newPropertyIndex = currentPropertyIndex; + } + currentPropertyIndex++; + + } while (newPropertyIndex == PROPERTY_NULL); + + /* + * grow the property chain + */ + if (! readSuccessful) + { + StgProperty emptyProperty; + ULARGE_INTEGER newSize; + ULONG propertyIndex; + ULONG lastProperty = 0; + ULONG blockCount = 0; + + /* + * obtain the new count of property blocks + */ + blockCount = BlockChainStream_GetCount( + storage->ancestorStorage->rootBlockChain)+1; + + /* + * initialize the size used by the property stream + */ + newSize.u.HighPart = 0; + newSize.u.LowPart = storage->bigBlockSize * blockCount; + + /* + * add a property block to the property chain + */ + BlockChainStream_SetSize(storage->ancestorStorage->rootBlockChain, newSize); + + /* + * memset the empty property in order to initialize the unused newly + * created property + */ + memset(&emptyProperty, 0, sizeof(StgProperty)); + + /* + * initialize them + */ + lastProperty = storage->bigBlockSize / PROPSET_BLOCK_SIZE * blockCount; + + for( + propertyIndex = newPropertyIndex; + propertyIndex < lastProperty; + propertyIndex++) + { + StorageImpl_WriteProperty( + storage->ancestorStorage, + propertyIndex, + &emptyProperty); + } + } + + return newPropertyIndex; +} + +/**************************************************************************** + * + * Internal Method + * + * Case insensitive comparaison of StgProperty.name by first considering + * their size. + * + * Returns <0 when newPrpoerty < currentProperty + * >0 when newPrpoerty > currentProperty + * 0 when newPrpoerty == currentProperty + */ +static LONG propertyNameCmp( + OLECHAR *newProperty, + OLECHAR *currentProperty) +{ + LONG diff = lstrlenW(newProperty) - lstrlenW(currentProperty); + + if (diff == 0) + { + /* + * We compare the string themselves only when they are of the same lenght + */ + diff = lstrcmpiW( newProperty, currentProperty); + } + + return diff; +} + +/**************************************************************************** + * + * Internal Method + * + * Properly link this new element in the property chain. + */ +static void updatePropertyChain( + StorageImpl *storage, + ULONG newPropertyIndex, + StgProperty newProperty) +{ + StgProperty currentProperty; + + /* + * Read the root property + */ + StorageImpl_ReadProperty(storage->ancestorStorage, + storage->rootPropertySetIndex, + ¤tProperty); + + if (currentProperty.dirProperty != PROPERTY_NULL) + { + /* + * The root storage contains some element, therefore, start the research + * for the appropriate location. + */ + BOOL found = 0; + ULONG current, next, previous, currentPropertyId; + + /* + * Keep the StgProperty sequence number of the storage first property + */ + currentPropertyId = currentProperty.dirProperty; + + /* + * Read + */ + StorageImpl_ReadProperty(storage->ancestorStorage, + currentProperty.dirProperty, + ¤tProperty); + + previous = currentProperty.previousProperty; + next = currentProperty.nextProperty; + current = currentPropertyId; + + while (found == 0) + { + LONG diff = propertyNameCmp( newProperty.name, currentProperty.name); + + if (diff < 0) + { + if (previous != PROPERTY_NULL) + { + StorageImpl_ReadProperty(storage->ancestorStorage, + previous, + ¤tProperty); + current = previous; + } + else + { + currentProperty.previousProperty = newPropertyIndex; + StorageImpl_WriteProperty(storage->ancestorStorage, + current, + ¤tProperty); + found = 1; + } + } + else if (diff > 0) + { + if (next != PROPERTY_NULL) + { + StorageImpl_ReadProperty(storage->ancestorStorage, + next, + ¤tProperty); + current = next; + } + else + { + currentProperty.nextProperty = newPropertyIndex; + StorageImpl_WriteProperty(storage->ancestorStorage, + current, + ¤tProperty); + found = 1; + } + } + else + { + /* + * Trying to insert an item with the same name in the + * subtree structure. + */ + assert(FALSE); + } + + previous = currentProperty.previousProperty; + next = currentProperty.nextProperty; + } + } + else + { + /* + * The root storage is empty, link the new property to it's dir property + */ + currentProperty.dirProperty = newPropertyIndex; + StorageImpl_WriteProperty(storage->ancestorStorage, + storage->rootPropertySetIndex, + ¤tProperty); + } +} + + +/************************************************************************* + * CopyTo (IStorage) + */ +HRESULT WINAPI StorageImpl_CopyTo( + IStorage* iface, + DWORD ciidExclude, /* [in] */ + const IID* rgiidExclude, /* [size_is][unique][in] */ + SNB snbExclude, /* [unique][in] */ + IStorage* pstgDest) /* [unique][in] */ +{ + IEnumSTATSTG *elements = 0; + STATSTG curElement, strStat; + HRESULT hr; + IStorage *pstgTmp, *pstgChild; + IStream *pstrTmp, *pstrChild; + + if ((ciidExclude != 0) || (rgiidExclude != NULL) || (snbExclude != NULL)) + UNIMPLEMENTED; + + Print(MAX_TRACE, ("(%p, %ld, %p, %p, %p)\n", + iface, ciidExclude, rgiidExclude, + snbExclude, pstgDest)); + + /* + * Perform a sanity check + */ + if ( pstgDest == 0 ) + return STG_E_INVALIDPOINTER; + + /* + * Enumerate the elements + */ + hr = IStorage_EnumElements( iface, 0, 0, 0, &elements ); + + if ( hr != S_OK ) + return hr; + + /* + * set the class ID + */ + IStorage_Stat( iface, &curElement, STATFLAG_NONAME); + IStorage_SetClass( pstgDest, &curElement.clsid ); + + do + { + /* + * Obtain the next element + */ + hr = IEnumSTATSTG_Next( elements, 1, &curElement, NULL ); + + if ( hr == S_FALSE ) + { + hr = S_OK; /* done, every element has been copied */ + break; + } + + if (curElement.type == STGTY_STORAGE) + { + /* + * open child source storage + */ + hr = IStorage_OpenStorage( iface, curElement.pwcsName, NULL, + STGM_READ|STGM_SHARE_EXCLUSIVE, + NULL, 0, &pstgChild ); + + if (hr != S_OK) + break; + + /* + * Check if destination storage is not a child of the source + * storage, which will cause an infinite loop + */ + if (pstgChild == pstgDest) + { + IEnumSTATSTG_Release(elements); + + return STG_E_ACCESSDENIED; + } + + /* + * create a new storage in destination storage + */ + hr = IStorage_CreateStorage( pstgDest, curElement.pwcsName, + STGM_FAILIFTHERE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, + 0, 0, + &pstgTmp ); + /* + * if it already exist, don't create a new one use this one + */ + if (hr == STG_E_FILEALREADYEXISTS) + { + hr = IStorage_OpenStorage( pstgDest, curElement.pwcsName, NULL, + STGM_WRITE|STGM_SHARE_EXCLUSIVE, + NULL, 0, &pstgTmp ); + } + + if (hr != S_OK) + break; + + + /* + * do the copy recursively + */ + hr = IStorage_CopyTo( pstgChild, ciidExclude, rgiidExclude, + snbExclude, pstgTmp ); + + IStorage_Release( pstgTmp ); + IStorage_Release( pstgChild ); + } + else if (curElement.type == STGTY_STREAM) + { + /* + * create a new stream in destination storage. If the stream already + * exist, it will be deleted and a new one will be created. + */ + hr = IStorage_CreateStream( pstgDest, curElement.pwcsName, + STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, + 0, 0, &pstrTmp ); + + if (hr != S_OK) + break; + + /* + * open child stream storage + */ + hr = IStorage_OpenStream( iface, curElement.pwcsName, NULL, + STGM_READ|STGM_SHARE_EXCLUSIVE, + 0, &pstrChild ); + + if (hr != S_OK) + break; + + /* + * Get the size of the source stream + */ + IStream_Stat( pstrChild, &strStat, STATFLAG_NONAME ); + + /* + * Set the size of the destination stream. + */ + IStream_SetSize(pstrTmp, strStat.cbSize); + + /* + * do the copy + */ + hr = IStream_CopyTo( pstrChild, pstrTmp, strStat.cbSize, + NULL, NULL ); + + IStream_Release( pstrTmp ); + IStream_Release( pstrChild ); + } + else + { + Print(MIN_TRACE, ("unknown element type: %ld\n", curElement.type)); + } + + } while (hr == S_OK); + + /* + * Clean-up + */ + IEnumSTATSTG_Release(elements); + + return hr; +} + +/************************************************************************* + * MoveElementTo (IStorage) + */ +HRESULT WINAPI StorageImpl_MoveElementTo( + IStorage* iface, + const OLECHAR *pwcsName, /* [string][in] */ + IStorage *pstgDest, /* [unique][in] */ + const OLECHAR *pwcsNewName,/* [string][in] */ + DWORD grfFlags) /* [in] */ +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/************************************************************************* + * Commit (IStorage) + */ +HRESULT WINAPI StorageImpl_Commit( + IStorage* iface, + DWORD grfCommitFlags)/* [in] */ +{ + UNIMPLEMENTED; + return S_OK; +} + +/************************************************************************* + * Revert (IStorage) + */ +HRESULT WINAPI StorageImpl_Revert( + IStorage* iface) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/************************************************************************* + * DestroyElement (IStorage) + * + * Stategy: This implementation is build this way for simplicity not for speed. + * I always delete the top most element of the enumeration and adjust + * the deleted element pointer all the time. This takes longer to + * do but allow to reinvoke DestroyElement whenever we encounter a + * storage object. The optimisation reside in the usage of another + * enumeration stategy that would give all the leaves of a storage + * first. (postfix order) + */ +HRESULT WINAPI StorageImpl_DestroyElement( + IStorage* iface, + const OLECHAR *pwcsName)/* [string][in] */ +{ + StorageImpl* const This=(StorageImpl*)iface; + + IEnumSTATSTGImpl* propertyEnumeration; + HRESULT hr = S_OK; + BOOL res; + StgProperty propertyToDelete; + StgProperty parentProperty; + ULONG foundPropertyIndexToDelete; + ULONG typeOfRelation; + ULONG parentPropertyId; + + Print(MAX_TRACE, ("(%p, %S)\n", + iface, pwcsName)); + + /* + * Perform a sanity check on the parameters. + */ + if (pwcsName==NULL) + return STG_E_INVALIDPOINTER; + + /* + * Create a property enumeration to search the property with the given name + */ + propertyEnumeration = IEnumSTATSTGImpl_Construct( + This->ancestorStorage, + This->rootPropertySetIndex); + + foundPropertyIndexToDelete = IEnumSTATSTGImpl_FindProperty( + propertyEnumeration, + pwcsName, + &propertyToDelete); + + IEnumSTATSTGImpl_Destroy(propertyEnumeration); + + if ( foundPropertyIndexToDelete == PROPERTY_NULL ) + { + return STG_E_FILENOTFOUND; + } + + /* + * Find the parent property of the property to delete (the one that + * link to it). If This->dirProperty == foundPropertyIndexToDelete, + * the parent is This. Otherwise, the parent is one of it's sibling... + */ + + /* + * First, read This's StgProperty.. + */ + res = StorageImpl_ReadProperty( + This->ancestorStorage, + This->rootPropertySetIndex, + &parentProperty); + + assert(res==TRUE); + + /* + * Second, check to see if by any chance the actual storage (This) is not + * the parent of the property to delete... We never know... + */ + if ( parentProperty.dirProperty == foundPropertyIndexToDelete ) + { + /* + * Set data as it would have been done in the else part... + */ + typeOfRelation = PROPERTY_RELATION_DIR; + parentPropertyId = This->rootPropertySetIndex; + } + else + { + /* + * Create a property enumeration to search the parent properties, and + * delete it once done. + */ + IEnumSTATSTGImpl* propertyEnumeration2; + + propertyEnumeration2 = IEnumSTATSTGImpl_Construct( + This->ancestorStorage, + This->rootPropertySetIndex); + + typeOfRelation = IEnumSTATSTGImpl_FindParentProperty( + propertyEnumeration2, + foundPropertyIndexToDelete, + &parentProperty, + &parentPropertyId); + + IEnumSTATSTGImpl_Destroy(propertyEnumeration2); + } + + if ( propertyToDelete.propertyType == PROPTYPE_STORAGE ) + { + hr = deleteStorageProperty( + This, + foundPropertyIndexToDelete, + propertyToDelete); + } + else if ( propertyToDelete.propertyType == PROPTYPE_STREAM ) + { + hr = deleteStreamProperty( + This, + foundPropertyIndexToDelete, + propertyToDelete); + } + + if (hr!=S_OK) + return hr; + + /* + * Adjust the property chain + */ + hr = adjustPropertyChain( + This, + propertyToDelete, + parentProperty, + parentPropertyId, + typeOfRelation); + + return hr; +} + + +/********************************************************************* + * + * Internal Method + * + * Perform the deletion of a complete storage node + * + */ +static HRESULT deleteStorageProperty( + StorageImpl *parentStorage, + ULONG indexOfPropertyToDelete, + StgProperty propertyToDelete) +{ + IEnumSTATSTG *elements = 0; + IStorage *childStorage = 0; + STATSTG currentElement; + HRESULT hr; + HRESULT destroyHr = S_OK; + + /* + * Open the storage and enumerate it + */ + hr = StorageBaseImpl_OpenStorage( + (IStorage*)parentStorage, + propertyToDelete.name, + 0, + STGM_SHARE_EXCLUSIVE, + 0, + 0, + &childStorage); + + if (hr != S_OK) + { + return hr; + } + + /* + * Enumerate the elements + */ + IStorage_EnumElements( childStorage, 0, 0, 0, &elements); + + do + { + /* + * Obtain the next element + */ + hr = IEnumSTATSTG_Next(elements, 1, ¤tElement, NULL); + if (hr==S_OK) + { + destroyHr = StorageImpl_DestroyElement( + (IStorage*)childStorage, + (OLECHAR*)currentElement.pwcsName); + + CoTaskMemFree(currentElement.pwcsName); + } + + /* + * We need to Reset the enumeration every time because we delete elements + * and the enumeration could be invalid + */ + IEnumSTATSTG_Reset(elements); + + } while ((hr == S_OK) && (destroyHr == S_OK)); + + /* + * Invalidate the property by zeroing it's name member. + */ + propertyToDelete.sizeOfNameString = 0; + + StorageImpl_WriteProperty(parentStorage->ancestorStorage, + indexOfPropertyToDelete, + &propertyToDelete); + + IStorage_Release(childStorage); + IEnumSTATSTG_Release(elements); + + return destroyHr; +} + +/********************************************************************* + * + * Internal Method + * + * Perform the deletion of a stream node + * + */ +static HRESULT deleteStreamProperty( + StorageImpl *parentStorage, + ULONG indexOfPropertyToDelete, + StgProperty propertyToDelete) +{ + IStream *pis; + HRESULT hr; + ULARGE_INTEGER size; + + size.u.HighPart = 0; + size.u.LowPart = 0; + + hr = StorageBaseImpl_OpenStream( + (IStorage*)parentStorage, + (OLECHAR*)propertyToDelete.name, + NULL, + STGM_WRITE | STGM_SHARE_EXCLUSIVE, + 0, + &pis); + + if (hr!=S_OK) + { + return(hr); + } + + /* + * Zap the stream + */ + hr = IStream_SetSize(pis, size); + + if(hr != S_OK) + { + return hr; + } + + /* + * Release the stream object. + */ + IStream_Release(pis); + + /* + * Invalidate the property by zeroing it's name member. + */ + propertyToDelete.sizeOfNameString = 0; + + /* + * Here we should re-read the property so we get the updated pointer + * but since we are here to zap it, I don't do it... + */ + StorageImpl_WriteProperty( + parentStorage->ancestorStorage, + indexOfPropertyToDelete, + &propertyToDelete); + + return S_OK; +} + +/********************************************************************* + * + * Internal Method + * + * Finds a placeholder for the StgProperty within the Storage + * + */ +static HRESULT findPlaceholder( + StorageImpl *storage, + ULONG propertyIndexToStore, + ULONG storePropertyIndex, + INT typeOfRelation) +{ + StgProperty storeProperty; + HRESULT hr = S_OK; + BOOL res = TRUE; + + /* + * Read the storage property + */ + res = StorageImpl_ReadProperty( + storage->ancestorStorage, + storePropertyIndex, + &storeProperty); + + if(! res) + { + return E_FAIL; + } + + if (typeOfRelation == PROPERTY_RELATION_PREVIOUS) + { + if (storeProperty.previousProperty != PROPERTY_NULL) + { + return findPlaceholder( + storage, + propertyIndexToStore, + storeProperty.previousProperty, + typeOfRelation); + } + else + { + storeProperty.previousProperty = propertyIndexToStore; + } + } + else if (typeOfRelation == PROPERTY_RELATION_NEXT) + { + if (storeProperty.nextProperty != PROPERTY_NULL) + { + return findPlaceholder( + storage, + propertyIndexToStore, + storeProperty.nextProperty, + typeOfRelation); + } + else + { + storeProperty.nextProperty = propertyIndexToStore; + } + } + else if (typeOfRelation == PROPERTY_RELATION_DIR) + { + if (storeProperty.dirProperty != PROPERTY_NULL) + { + return findPlaceholder( + storage, + propertyIndexToStore, + storeProperty.dirProperty, + typeOfRelation); + } + else + { + storeProperty.dirProperty = propertyIndexToStore; + } + } + + hr = StorageImpl_WriteProperty( + storage->ancestorStorage, + storePropertyIndex, + &storeProperty); + + if(! hr) + { + return E_FAIL; + } + + return S_OK; +} + +/************************************************************************* + * + * Internal Method + * + * This method takes the previous and the next property link of a property + * to be deleted and find them a place in the Storage. + */ +static HRESULT adjustPropertyChain( + StorageImpl *This, + StgProperty propertyToDelete, + StgProperty parentProperty, + ULONG parentPropertyId, + INT typeOfRelation) +{ + ULONG newLinkProperty = PROPERTY_NULL; + BOOL needToFindAPlaceholder = FALSE; + ULONG storeNode = PROPERTY_NULL; + ULONG toStoreNode = PROPERTY_NULL; + INT relationType = 0; + HRESULT hr = S_OK; + BOOL res = TRUE; + + if (typeOfRelation == PROPERTY_RELATION_PREVIOUS) + { + if (propertyToDelete.previousProperty != PROPERTY_NULL) + { + /* + * Set the parent previous to the property to delete previous + */ + newLinkProperty = propertyToDelete.previousProperty; + + if (propertyToDelete.nextProperty != PROPERTY_NULL) + { + /* + * We also need to find a storage for the other link, setup variables + * to do this at the end... + */ + needToFindAPlaceholder = TRUE; + storeNode = propertyToDelete.previousProperty; + toStoreNode = propertyToDelete.nextProperty; + relationType = PROPERTY_RELATION_NEXT; + } + } + else if (propertyToDelete.nextProperty != PROPERTY_NULL) + { + /* + * Set the parent previous to the property to delete next + */ + newLinkProperty = propertyToDelete.nextProperty; + } + + /* + * Link it for real... + */ + parentProperty.previousProperty = newLinkProperty; + + } + else if (typeOfRelation == PROPERTY_RELATION_NEXT) + { + if (propertyToDelete.previousProperty != PROPERTY_NULL) + { + /* + * Set the parent next to the property to delete next previous + */ + newLinkProperty = propertyToDelete.previousProperty; + + if (propertyToDelete.nextProperty != PROPERTY_NULL) + { + /* + * We also need to find a storage for the other link, setup variables + * to do this at the end... + */ + needToFindAPlaceholder = TRUE; + storeNode = propertyToDelete.previousProperty; + toStoreNode = propertyToDelete.nextProperty; + relationType = PROPERTY_RELATION_NEXT; + } + } + else if (propertyToDelete.nextProperty != PROPERTY_NULL) + { + /* + * Set the parent next to the property to delete next + */ + newLinkProperty = propertyToDelete.nextProperty; + } + + /* + * Link it for real... + */ + parentProperty.nextProperty = newLinkProperty; + } + else /* (typeOfRelation == PROPERTY_RELATION_DIR) */ + { + if (propertyToDelete.previousProperty != PROPERTY_NULL) + { + /* + * Set the parent dir to the property to delete previous + */ + newLinkProperty = propertyToDelete.previousProperty; + + if (propertyToDelete.nextProperty != PROPERTY_NULL) + { + /* + * We also need to find a storage for the other link, setup variables + * to do this at the end... + */ + needToFindAPlaceholder = TRUE; + storeNode = propertyToDelete.previousProperty; + toStoreNode = propertyToDelete.nextProperty; + relationType = PROPERTY_RELATION_NEXT; + } + } + else if (propertyToDelete.nextProperty != PROPERTY_NULL) + { + /* + * Set the parent dir to the property to delete next + */ + newLinkProperty = propertyToDelete.nextProperty; + } + + /* + * Link it for real... + */ + parentProperty.dirProperty = newLinkProperty; + } + + /* + * Write back the parent property + */ + res = StorageImpl_WriteProperty( + This->ancestorStorage, + parentPropertyId, + &parentProperty); + if(! res) + { + return E_FAIL; + } + + /* + * If a placeholder is required for the other link, then, find one and + * get out of here... + */ + if (needToFindAPlaceholder) + { + hr = findPlaceholder( + This, + toStoreNode, + storeNode, + relationType); + } + + return hr; +} + + +/****************************************************************************** + * SetElementTimes (IStorage) + */ +HRESULT WINAPI StorageImpl_SetElementTimes( + IStorage* iface, + const OLECHAR *pwcsName,/* [string][in] */ + const FILETIME *pctime, /* [in] */ + const FILETIME *patime, /* [in] */ + const FILETIME *pmtime) /* [in] */ +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +/****************************************************************************** + * SetStateBits (IStorage) + */ +HRESULT WINAPI StorageImpl_SetStateBits( + IStorage* iface, + DWORD grfStateBits,/* [in] */ + DWORD grfMask) /* [in] */ +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +HRESULT StorageImpl_Construct( + StorageImpl* This, + HANDLE hFile, + ILockBytes* pLkbyt, + DWORD openFlags, + BOOL fileBased, + BOOL fileCreate) +{ + HRESULT hr = S_OK; + StgProperty currentProperty; + BOOL readSuccessful; + ULONG currentPropertyIndex; + + if ( FAILED( validateSTGM(openFlags) )) + return STG_E_INVALIDFLAG; + + memset(This, 0, sizeof(StorageImpl)); + + /* + * Initialize the virtual fgunction table. + */ + ICOM_VTBL(This) = &Storage32Impl_Vtbl; + This->v_destructor = &StorageImpl_Destroy; + + /* + * This is the top-level storage so initialize the ancester pointer + * to this. + */ + This->ancestorStorage = This; + + /* + * Initialize the physical support of the storage. + */ + This->hFile = hFile; + + /* + * Initialize the big block cache. + */ + This->bigBlockSize = DEF_BIG_BLOCK_SIZE; + This->smallBlockSize = DEF_SMALL_BLOCK_SIZE; + This->bigBlockFile = BIGBLOCKFILE_Construct(hFile, + pLkbyt, + openFlags, + This->bigBlockSize, + fileBased); + + if (This->bigBlockFile == 0) + return E_FAIL; + + if (fileCreate) + { + ULARGE_INTEGER size; + BYTE* bigBlockBuffer; + + /* + * Initialize all header variables: + * - The big block depot consists of one block and it is at block 0 + * - The properties start at block 1 + * - There is no small block depot + */ + memset( This->bigBlockDepotStart, + BLOCK_UNUSED, + sizeof(This->bigBlockDepotStart)); + + This->bigBlockDepotCount = 1; + This->bigBlockDepotStart[0] = 0; + This->rootStartBlock = 1; + This->smallBlockDepotStart = BLOCK_END_OF_CHAIN; + This->bigBlockSizeBits = DEF_BIG_BLOCK_SIZE_BITS; + This->smallBlockSizeBits = DEF_SMALL_BLOCK_SIZE_BITS; + This->extBigBlockDepotStart = BLOCK_END_OF_CHAIN; + This->extBigBlockDepotCount = 0; + + StorageImpl_SaveFileHeader(This); + + /* + * Add one block for the big block depot and one block for the properties + */ + size.u.HighPart = 0; + size.u.LowPart = This->bigBlockSize * 3; + BIGBLOCKFILE_SetSize(This->bigBlockFile, size); + + /* + * Initialize the big block depot + */ + bigBlockBuffer = StorageImpl_GetBigBlock(This, 0); + memset(bigBlockBuffer, BLOCK_UNUSED, This->bigBlockSize); + StorageUtl_WriteDWord(bigBlockBuffer, 0, BLOCK_SPECIAL); + StorageUtl_WriteDWord(bigBlockBuffer, sizeof(ULONG), BLOCK_END_OF_CHAIN); + StorageImpl_ReleaseBigBlock(This, bigBlockBuffer); + } + else + { + /* + * Load the header for the file. + */ + hr = StorageImpl_LoadFileHeader(This); + + if (FAILED(hr)) + { + BIGBLOCKFILE_Destructor(This->bigBlockFile); + + return hr; + } + } + + /* + * There is no block depot cached yet. + */ + This->indexBlockDepotCached = 0xFFFFFFFF; + + /* + * Start searching for free blocks with block 0. + */ + This->prevFreeBlock = 0; + + /* + * Create the block chain abstractions. + */ + This->rootBlockChain = + BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL); + + This->smallBlockDepotChain = BlockChainStream_Construct( + This, + &This->smallBlockDepotStart, + PROPERTY_NULL); + + /* + * Write the root property + */ + if (fileCreate) + { + StgProperty rootProp; + /* + * Initialize the property chain + */ + memset(&rootProp, 0, sizeof(rootProp)); + MultiByteToWideChar( CP_ACP, 0, rootPropertyName, -1, rootProp.name, + sizeof(rootProp.name)/sizeof(WCHAR) ); + rootProp.sizeOfNameString = (lstrlenW(rootProp.name)+1) * sizeof(WCHAR); + rootProp.propertyType = PROPTYPE_ROOT; + rootProp.previousProperty = PROPERTY_NULL; + rootProp.nextProperty = PROPERTY_NULL; + rootProp.dirProperty = PROPERTY_NULL; + rootProp.startingBlock = BLOCK_END_OF_CHAIN; + rootProp.size.u.HighPart = 0; + rootProp.size.u.LowPart = 0; + + StorageImpl_WriteProperty(This, 0, &rootProp); + } + + /* + * Find the ID of the root int he property sets. + */ + currentPropertyIndex = 0; + + do + { + readSuccessful = StorageImpl_ReadProperty( + This, + currentPropertyIndex, + ¤tProperty); + + if (readSuccessful) + { + if ( (currentProperty.sizeOfNameString != 0 ) && + (currentProperty.propertyType == PROPTYPE_ROOT) ) + { + This->rootPropertySetIndex = currentPropertyIndex; + } + } + + currentPropertyIndex++; + + } while (readSuccessful && (This->rootPropertySetIndex == PROPERTY_NULL) ); + + if (!readSuccessful) + { + /* TODO CLEANUP */ + return E_FAIL; + } + + /* + * Create the block chain abstraction for the small block root chain. + */ + This->smallBlockRootChain = BlockChainStream_Construct( + This, + NULL, + This->rootPropertySetIndex); + + return hr; +} + +void StorageImpl_Destroy( + StorageImpl* This) +{ + Print(MAX_TRACE, ("(%p)\n", This)); + + BlockChainStream_Destroy(This->smallBlockRootChain); + BlockChainStream_Destroy(This->rootBlockChain); + BlockChainStream_Destroy(This->smallBlockDepotChain); + + BIGBLOCKFILE_Destructor(This->bigBlockFile); + return; +} + +/****************************************************************************** + * Storage32Impl_GetNextFreeBigBlock + * + * Returns the index of the next free big block. + * If the big block depot is filled, this method will enlarge it. + * + */ +ULONG StorageImpl_GetNextFreeBigBlock( + StorageImpl* This) +{ + ULONG depotBlockIndexPos; + void *depotBuffer; + ULONG depotBlockOffset; + ULONG blocksPerDepot = This->bigBlockSize / sizeof(ULONG); + ULONG nextBlockIndex = BLOCK_SPECIAL; + int depotIndex = 0; + ULONG freeBlock = BLOCK_UNUSED; + + depotIndex = This->prevFreeBlock / blocksPerDepot; + depotBlockOffset = (This->prevFreeBlock % blocksPerDepot) * sizeof(ULONG); + + /* + * Scan the entire big block depot until we find a block marked free + */ + while (nextBlockIndex != BLOCK_UNUSED) + { + if (depotIndex < COUNT_BBDEPOTINHEADER) + { + depotBlockIndexPos = This->bigBlockDepotStart[depotIndex]; + + /* + * Grow the primary depot. + */ + if (depotBlockIndexPos == BLOCK_UNUSED) + { + depotBlockIndexPos = depotIndex*blocksPerDepot; + + /* + * Add a block depot. + */ + Storage32Impl_AddBlockDepot(This, depotBlockIndexPos); + This->bigBlockDepotCount++; + This->bigBlockDepotStart[depotIndex] = depotBlockIndexPos; + + /* + * Flag it as a block depot. + */ + StorageImpl_SetNextBlockInChain(This, + depotBlockIndexPos, + BLOCK_SPECIAL); + + /* Save new header information. + */ + StorageImpl_SaveFileHeader(This); + } + } + else + { + depotBlockIndexPos = Storage32Impl_GetExtDepotBlock(This, depotIndex); + + if (depotBlockIndexPos == BLOCK_UNUSED) + { + /* + * Grow the extended depot. + */ + ULONG extIndex = BLOCK_UNUSED; + ULONG numExtBlocks = depotIndex - COUNT_BBDEPOTINHEADER; + ULONG extBlockOffset = numExtBlocks % (blocksPerDepot - 1); + + if (extBlockOffset == 0) + { + /* We need an extended block. + */ + extIndex = Storage32Impl_AddExtBlockDepot(This); + This->extBigBlockDepotCount++; + depotBlockIndexPos = extIndex + 1; + } + else + depotBlockIndexPos = depotIndex * blocksPerDepot; + + /* + * Add a block depot and mark it in the extended block. + */ + Storage32Impl_AddBlockDepot(This, depotBlockIndexPos); + This->bigBlockDepotCount++; + Storage32Impl_SetExtDepotBlock(This, depotIndex, depotBlockIndexPos); + + /* Flag the block depot. + */ + StorageImpl_SetNextBlockInChain(This, + depotBlockIndexPos, + BLOCK_SPECIAL); + + /* If necessary, flag the extended depot block. + */ + if (extIndex != BLOCK_UNUSED) + StorageImpl_SetNextBlockInChain(This, extIndex, BLOCK_EXTBBDEPOT); + + /* Save header information. + */ + StorageImpl_SaveFileHeader(This); + } + } + + depotBuffer = StorageImpl_GetROBigBlock(This, depotBlockIndexPos); + + if (depotBuffer != 0) + { + while ( ( (depotBlockOffset/sizeof(ULONG) ) < blocksPerDepot) && + ( nextBlockIndex != BLOCK_UNUSED)) + { + StorageUtl_ReadDWord(depotBuffer, depotBlockOffset, &nextBlockIndex); + + if (nextBlockIndex == BLOCK_UNUSED) + { + freeBlock = (depotIndex * blocksPerDepot) + + (depotBlockOffset/sizeof(ULONG)); + } + + depotBlockOffset += sizeof(ULONG); + } + + StorageImpl_ReleaseBigBlock(This, depotBuffer); + } + + depotIndex++; + depotBlockOffset = 0; + } + + This->prevFreeBlock = freeBlock; + + return freeBlock; +} + +/****************************************************************************** + * Storage32Impl_AddBlockDepot + * + * This will create a depot block, essentially it is a block initialized + * to BLOCK_UNUSEDs. + */ +void Storage32Impl_AddBlockDepot(StorageImpl* This, ULONG blockIndex) +{ + BYTE* blockBuffer; + + blockBuffer = StorageImpl_GetBigBlock(This, blockIndex); + + /* + * Initialize blocks as free + */ + memset(blockBuffer, BLOCK_UNUSED, This->bigBlockSize); + + StorageImpl_ReleaseBigBlock(This, blockBuffer); +} + +/****************************************************************************** + * Storage32Impl_GetExtDepotBlock + * + * Returns the index of the block that corresponds to the specified depot + * index. This method is only for depot indexes equal or greater than + * COUNT_BBDEPOTINHEADER. + */ +ULONG Storage32Impl_GetExtDepotBlock(StorageImpl* This, ULONG depotIndex) +{ + ULONG depotBlocksPerExtBlock = (This->bigBlockSize / sizeof(ULONG)) - 1; + ULONG numExtBlocks = depotIndex - COUNT_BBDEPOTINHEADER; + ULONG extBlockCount = numExtBlocks / depotBlocksPerExtBlock; + ULONG extBlockOffset = numExtBlocks % depotBlocksPerExtBlock; + ULONG blockIndex = BLOCK_UNUSED; + ULONG extBlockIndex = This->extBigBlockDepotStart; + + assert(depotIndex >= COUNT_BBDEPOTINHEADER); + + if (This->extBigBlockDepotStart == BLOCK_END_OF_CHAIN) + return BLOCK_UNUSED; + + while (extBlockCount > 0) + { + extBlockIndex = Storage32Impl_GetNextExtendedBlock(This, extBlockIndex); + extBlockCount--; + } + + if (extBlockIndex != BLOCK_UNUSED) + { + BYTE* depotBuffer; + + depotBuffer = StorageImpl_GetROBigBlock(This, extBlockIndex); + + if (depotBuffer != 0) + { + StorageUtl_ReadDWord(depotBuffer, + extBlockOffset * sizeof(ULONG), + &blockIndex); + + StorageImpl_ReleaseBigBlock(This, depotBuffer); + } + } + + return blockIndex; +} + +/****************************************************************************** + * Storage32Impl_SetExtDepotBlock + * + * Associates the specified block index to the specified depot index. + * This method is only for depot indexes equal or greater than + * COUNT_BBDEPOTINHEADER. + */ +void Storage32Impl_SetExtDepotBlock(StorageImpl* This, + ULONG depotIndex, + ULONG blockIndex) +{ + ULONG depotBlocksPerExtBlock = (This->bigBlockSize / sizeof(ULONG)) - 1; + ULONG numExtBlocks = depotIndex - COUNT_BBDEPOTINHEADER; + ULONG extBlockCount = numExtBlocks / depotBlocksPerExtBlock; + ULONG extBlockOffset = numExtBlocks % depotBlocksPerExtBlock; + ULONG extBlockIndex = This->extBigBlockDepotStart; + + assert(depotIndex >= COUNT_BBDEPOTINHEADER); + + while (extBlockCount > 0) + { + extBlockIndex = Storage32Impl_GetNextExtendedBlock(This, extBlockIndex); + extBlockCount--; + } + + if (extBlockIndex != BLOCK_UNUSED) + { + BYTE* depotBuffer; + + depotBuffer = StorageImpl_GetBigBlock(This, extBlockIndex); + + if (depotBuffer != 0) + { + StorageUtl_WriteDWord(depotBuffer, + extBlockOffset * sizeof(ULONG), + blockIndex); + + StorageImpl_ReleaseBigBlock(This, depotBuffer); + } + } +} + +/****************************************************************************** + * Storage32Impl_AddExtBlockDepot + * + * Creates an extended depot block. + */ +ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This) +{ + ULONG numExtBlocks = This->extBigBlockDepotCount; + ULONG nextExtBlock = This->extBigBlockDepotStart; + BYTE* depotBuffer = NULL; + ULONG index = BLOCK_UNUSED; + ULONG nextBlockOffset = This->bigBlockSize - sizeof(ULONG); + ULONG blocksPerDepotBlock = This->bigBlockSize / sizeof(ULONG); + ULONG depotBlocksPerExtBlock = blocksPerDepotBlock - 1; + + index = (COUNT_BBDEPOTINHEADER + (numExtBlocks * depotBlocksPerExtBlock)) * + blocksPerDepotBlock; + + if ((numExtBlocks == 0) && (nextExtBlock == BLOCK_END_OF_CHAIN)) + { + /* + * The first extended block. + */ + This->extBigBlockDepotStart = index; + } + else + { + int i; + /* + * Follow the chain to the last one. + */ + for (i = 0; i < (numExtBlocks - 1); i++) + { + nextExtBlock = Storage32Impl_GetNextExtendedBlock(This, nextExtBlock); + } + + /* + * Add the new extended block to the chain. + */ + depotBuffer = StorageImpl_GetBigBlock(This, nextExtBlock); + StorageUtl_WriteDWord(depotBuffer, nextBlockOffset, index); + StorageImpl_ReleaseBigBlock(This, depotBuffer); + } + + /* + * Initialize this block. + */ + depotBuffer = StorageImpl_GetBigBlock(This, index); + memset(depotBuffer, BLOCK_UNUSED, This->bigBlockSize); + StorageImpl_ReleaseBigBlock(This, depotBuffer); + + return index; +} + +/****************************************************************************** + * Storage32Impl_FreeBigBlock + * + * This method will flag the specified block as free in the big block depot. + */ +void StorageImpl_FreeBigBlock( + StorageImpl* This, + ULONG blockIndex) +{ + StorageImpl_SetNextBlockInChain(This, blockIndex, BLOCK_UNUSED); + + if (blockIndex < This->prevFreeBlock) + This->prevFreeBlock = blockIndex; +} + +/************************************************************************ + * Storage32Impl_GetNextBlockInChain + * + * This method will retrieve the block index of the next big block in + * in the chain. + * + * Params: This - Pointer to the Storage object. + * blockIndex - Index of the block to retrieve the chain + * for. + * + * Returns: This method returns the index of the next block in the chain. + * It will return the constants: + * BLOCK_SPECIAL - If the block given was not part of a + * chain. + * BLOCK_END_OF_CHAIN - If the block given was the last in + * a chain. + * BLOCK_UNUSED - If the block given was not past of a chain + * and is available. + * BLOCK_EXTBBDEPOT - This block is part of the extended + * big block depot. + * + * See Windows documentation for more details on IStorage methods. + */ +ULONG StorageImpl_GetNextBlockInChain( + StorageImpl* This, + ULONG blockIndex) +{ + ULONG offsetInDepot = blockIndex * sizeof (ULONG); + ULONG depotBlockCount = offsetInDepot / This->bigBlockSize; + ULONG depotBlockOffset = offsetInDepot % This->bigBlockSize; + ULONG nextBlockIndex = BLOCK_SPECIAL; + void* depotBuffer; + ULONG depotBlockIndexPos; + + assert(depotBlockCount < This->bigBlockDepotCount); + + /* + * Cache the currently accessed depot block. + */ + if (depotBlockCount != This->indexBlockDepotCached) + { + This->indexBlockDepotCached = depotBlockCount; + + if (depotBlockCount < COUNT_BBDEPOTINHEADER) + { + depotBlockIndexPos = This->bigBlockDepotStart[depotBlockCount]; + } + else + { + /* + * We have to look in the extended depot. + */ + depotBlockIndexPos = Storage32Impl_GetExtDepotBlock(This, depotBlockCount); + } + + depotBuffer = StorageImpl_GetROBigBlock(This, depotBlockIndexPos); + + if (depotBuffer!=0) + { + int index; + + for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++) + { + StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), &nextBlockIndex); + This->blockDepotCached[index] = nextBlockIndex; + } + + StorageImpl_ReleaseBigBlock(This, depotBuffer); + } + } + + nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)]; + + return nextBlockIndex; +} + +/****************************************************************************** + * Storage32Impl_GetNextExtendedBlock + * + * Given an extended block this method will return the next extended block. + * + * NOTES: + * The last ULONG of an extended block is the block index of the next + * extended block. Extended blocks are marked as BLOCK_EXTBBDEPOT in the + * depot. + * + * Return values: + * - The index of the next extended block + * - BLOCK_UNUSED: there is no next extended block. + * - Any other return values denotes failure. + */ +ULONG Storage32Impl_GetNextExtendedBlock(StorageImpl* This, ULONG blockIndex) +{ + ULONG nextBlockIndex = BLOCK_SPECIAL; + ULONG depotBlockOffset = This->bigBlockSize - sizeof(ULONG); + void* depotBuffer; + + depotBuffer = StorageImpl_GetROBigBlock(This, blockIndex); + + if (depotBuffer!=0) + { + StorageUtl_ReadDWord(depotBuffer, depotBlockOffset, &nextBlockIndex); + + StorageImpl_ReleaseBigBlock(This, depotBuffer); + } + + return nextBlockIndex; +} + +/****************************************************************************** + * Storage32Impl_SetNextBlockInChain + * + * This method will write the index of the specified block's next block + * in the big block depot. + * + * For example: to create the chain 3 -> 1 -> 7 -> End of Chain + * do the following + * + * Storage32Impl_SetNextBlockInChain(This, 3, 1); + * Storage32Impl_SetNextBlockInChain(This, 1, 7); + * Storage32Impl_SetNextBlockInChain(This, 7, BLOCK_END_OF_CHAIN); + * + */ +void StorageImpl_SetNextBlockInChain( + StorageImpl* This, + ULONG blockIndex, + ULONG nextBlock) +{ + ULONG offsetInDepot = blockIndex * sizeof (ULONG); + ULONG depotBlockCount = offsetInDepot / This->bigBlockSize; + ULONG depotBlockOffset = offsetInDepot % This->bigBlockSize; + ULONG depotBlockIndexPos; + void* depotBuffer; + + assert(depotBlockCount < This->bigBlockDepotCount); + assert(blockIndex != nextBlock); + + if (depotBlockCount < COUNT_BBDEPOTINHEADER) + { + depotBlockIndexPos = This->bigBlockDepotStart[depotBlockCount]; + } + else + { + /* + * We have to look in the extended depot. + */ + depotBlockIndexPos = Storage32Impl_GetExtDepotBlock(This, depotBlockCount); + } + + depotBuffer = StorageImpl_GetBigBlock(This, depotBlockIndexPos); + + if (depotBuffer!=0) + { + StorageUtl_WriteDWord(depotBuffer, depotBlockOffset, nextBlock); + StorageImpl_ReleaseBigBlock(This, depotBuffer); + } + + /* + * Update the cached block depot, if necessary. + */ + if (depotBlockCount == This->indexBlockDepotCached) + { + This->blockDepotCached[depotBlockOffset/sizeof(ULONG)] = nextBlock; + } +} + +/****************************************************************************** + * Storage32Impl_LoadFileHeader + * + * This method will read in the file header, i.e. big block index -1. + */ +HRESULT StorageImpl_LoadFileHeader( + StorageImpl* This) +{ + HRESULT hr = STG_E_FILENOTFOUND; + void* headerBigBlock = NULL; + int index; + + /* + * Get a pointer to the big block of data containing the header. + */ + headerBigBlock = StorageImpl_GetROBigBlock(This, -1); + + /* + * Extract the information from the header. + */ + if (headerBigBlock!=0) + { + /* + * Check for the "magic number" signature and return an error if it is not + * found. + */ + if (memcmp(headerBigBlock, STORAGE_oldmagic, sizeof(STORAGE_oldmagic))==0) + { + StorageImpl_ReleaseBigBlock(This, headerBigBlock); + return STG_E_OLDFORMAT; + } + + if (memcmp(headerBigBlock, STORAGE_magic, sizeof(STORAGE_magic))!=0) + { + StorageImpl_ReleaseBigBlock(This, headerBigBlock); + return STG_E_INVALIDHEADER; + } + + StorageUtl_ReadWord( + headerBigBlock, + OFFSET_BIGBLOCKSIZEBITS, + &This->bigBlockSizeBits); + + StorageUtl_ReadWord( + headerBigBlock, + OFFSET_SMALLBLOCKSIZEBITS, + &This->smallBlockSizeBits); + + StorageUtl_ReadDWord( + headerBigBlock, + OFFSET_BBDEPOTCOUNT, + &This->bigBlockDepotCount); + + StorageUtl_ReadDWord( + headerBigBlock, + OFFSET_ROOTSTARTBLOCK, + &This->rootStartBlock); + + StorageUtl_ReadDWord( + headerBigBlock, + OFFSET_SBDEPOTSTART, + &This->smallBlockDepotStart); + + StorageUtl_ReadDWord( + headerBigBlock, + OFFSET_EXTBBDEPOTSTART, + &This->extBigBlockDepotStart); + + StorageUtl_ReadDWord( + headerBigBlock, + OFFSET_EXTBBDEPOTCOUNT, + &This->extBigBlockDepotCount); + + for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++) + { + StorageUtl_ReadDWord( + headerBigBlock, + OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index), + &(This->bigBlockDepotStart[index])); + } + + /* + * Make the bitwise arithmetic to get the size of the blocks in bytes. + */ + if ((1 << 2) == 4) + { + This->bigBlockSize = 0x000000001 << (DWORD)This->bigBlockSizeBits; + This->smallBlockSize = 0x000000001 << (DWORD)This->smallBlockSizeBits; + } + else + { + This->bigBlockSize = 0x000000001 >> (DWORD)This->bigBlockSizeBits; + This->smallBlockSize = 0x000000001 >> (DWORD)This->smallBlockSizeBits; + } + + /* + * Right now, the code is making some assumptions about the size of the + * blocks, just make sure they are what we're expecting. + */ + assert( (This->bigBlockSize==DEF_BIG_BLOCK_SIZE) && + (This->smallBlockSize==DEF_SMALL_BLOCK_SIZE)); + + /* + * Release the block. + */ + StorageImpl_ReleaseBigBlock(This, headerBigBlock); + + hr = S_OK; + } + + return hr; +} + +/****************************************************************************** + * Storage32Impl_SaveFileHeader + * + * This method will save to the file the header, i.e. big block -1. + */ +void StorageImpl_SaveFileHeader( + StorageImpl* This) +{ + BYTE headerBigBlock[BIG_BLOCK_SIZE]; + int index; + BOOL success; + + /* + * Get a pointer to the big block of data containing the header. + */ + success = StorageImpl_ReadBigBlock(This, -1, headerBigBlock); + + /* + * If the block read failed, the file is probably new. + */ + if (!success) + { + /* + * Initialize for all unknown fields. + */ + memset(headerBigBlock, 0, BIG_BLOCK_SIZE); + + /* + * Initialize the magic number. + */ + memcpy(headerBigBlock, STORAGE_magic, sizeof(STORAGE_magic)); + + /* + * And a bunch of things we don't know what they mean + */ + StorageUtl_WriteWord(headerBigBlock, 0x18, 0x3b); + StorageUtl_WriteWord(headerBigBlock, 0x1a, 0x3); + StorageUtl_WriteWord(headerBigBlock, 0x1c, (WORD)-2); + StorageUtl_WriteDWord(headerBigBlock, 0x38, (DWORD)0x1000); + StorageUtl_WriteDWord(headerBigBlock, 0x40, (DWORD)0x0001); + } + + /* + * Write the information to the header. + */ + if (headerBigBlock!=0) + { + StorageUtl_WriteWord( + headerBigBlock, + OFFSET_BIGBLOCKSIZEBITS, + This->bigBlockSizeBits); + + StorageUtl_WriteWord( + headerBigBlock, + OFFSET_SMALLBLOCKSIZEBITS, + This->smallBlockSizeBits); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_BBDEPOTCOUNT, + This->bigBlockDepotCount); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_ROOTSTARTBLOCK, + This->rootStartBlock); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_SBDEPOTSTART, + This->smallBlockDepotStart); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_EXTBBDEPOTSTART, + This->extBigBlockDepotStart); + + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_EXTBBDEPOTCOUNT, + This->extBigBlockDepotCount); + + for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++) + { + StorageUtl_WriteDWord( + headerBigBlock, + OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index), + (This->bigBlockDepotStart[index])); + } + } + + /* + * Write the big block back to the file. + */ + StorageImpl_WriteBigBlock(This, -1, headerBigBlock); +} + +/****************************************************************************** + * Storage32Impl_ReadProperty + * + * This method will read the specified property from the property chain. + */ +BOOL StorageImpl_ReadProperty( + StorageImpl* This, + ULONG index, + StgProperty* buffer) +{ + BYTE currentProperty[PROPSET_BLOCK_SIZE]; + ULARGE_INTEGER offsetInPropSet; + BOOL readSuccessful; + ULONG bytesRead; + + offsetInPropSet.u.HighPart = 0; + offsetInPropSet.u.LowPart = index * PROPSET_BLOCK_SIZE; + + readSuccessful = BlockChainStream_ReadAt( + This->rootBlockChain, + offsetInPropSet, + PROPSET_BLOCK_SIZE, + currentProperty, + &bytesRead); + + if (readSuccessful) + { + memset(buffer->name, 0, sizeof(buffer->name)); + memcpy( + buffer->name, + currentProperty+OFFSET_PS_NAME, + PROPERTY_NAME_BUFFER_LEN ); + + memcpy(&buffer->propertyType, currentProperty + OFFSET_PS_PROPERTYTYPE, 1); + + StorageUtl_ReadWord( + currentProperty, + OFFSET_PS_NAMELENGTH, + &buffer->sizeOfNameString); + + StorageUtl_ReadDWord( + currentProperty, + OFFSET_PS_PREVIOUSPROP, + &buffer->previousProperty); + + StorageUtl_ReadDWord( + currentProperty, + OFFSET_PS_NEXTPROP, + &buffer->nextProperty); + + StorageUtl_ReadDWord( + currentProperty, + OFFSET_PS_DIRPROP, + &buffer->dirProperty); + + StorageUtl_ReadGUID( + currentProperty, + OFFSET_PS_GUID, + &buffer->propertyUniqueID); + + StorageUtl_ReadDWord( + currentProperty, + OFFSET_PS_TSS1, + &buffer->timeStampS1); + + StorageUtl_ReadDWord( + currentProperty, + OFFSET_PS_TSD1, + &buffer->timeStampD1); + + StorageUtl_ReadDWord( + currentProperty, + OFFSET_PS_TSS2, + &buffer->timeStampS2); + + StorageUtl_ReadDWord( + currentProperty, + OFFSET_PS_TSD2, + &buffer->timeStampD2); + + StorageUtl_ReadDWord( + currentProperty, + OFFSET_PS_STARTBLOCK, + &buffer->startingBlock); + + StorageUtl_ReadDWord( + currentProperty, + OFFSET_PS_SIZE, + &buffer->size.u.LowPart); + + buffer->size.u.HighPart = 0; + } + + return readSuccessful; +} + +/********************************************************************* + * Write the specified property into the property chain + */ +BOOL StorageImpl_WriteProperty( + StorageImpl* This, + ULONG index, + StgProperty* buffer) +{ + BYTE currentProperty[PROPSET_BLOCK_SIZE]; + ULARGE_INTEGER offsetInPropSet; + BOOL writeSuccessful; + ULONG bytesWritten; + + offsetInPropSet.u.HighPart = 0; + offsetInPropSet.u.LowPart = index * PROPSET_BLOCK_SIZE; + + memset(currentProperty, 0, PROPSET_BLOCK_SIZE); + + memcpy( + currentProperty + OFFSET_PS_NAME, + buffer->name, + PROPERTY_NAME_BUFFER_LEN ); + + memcpy(currentProperty + OFFSET_PS_PROPERTYTYPE, &buffer->propertyType, 1); + + StorageUtl_WriteWord( + currentProperty, + OFFSET_PS_NAMELENGTH, + buffer->sizeOfNameString); + + StorageUtl_WriteDWord( + currentProperty, + OFFSET_PS_PREVIOUSPROP, + buffer->previousProperty); + + StorageUtl_WriteDWord( + currentProperty, + OFFSET_PS_NEXTPROP, + buffer->nextProperty); + + StorageUtl_WriteDWord( + currentProperty, + OFFSET_PS_DIRPROP, + buffer->dirProperty); + + StorageUtl_WriteGUID( + currentProperty, + OFFSET_PS_GUID, + &buffer->propertyUniqueID); + + StorageUtl_WriteDWord( + currentProperty, + OFFSET_PS_TSS1, + buffer->timeStampS1); + + StorageUtl_WriteDWord( + currentProperty, + OFFSET_PS_TSD1, + buffer->timeStampD1); + + StorageUtl_WriteDWord( + currentProperty, + OFFSET_PS_TSS2, + buffer->timeStampS2); + + StorageUtl_WriteDWord( + currentProperty, + OFFSET_PS_TSD2, + buffer->timeStampD2); + + StorageUtl_WriteDWord( + currentProperty, + OFFSET_PS_STARTBLOCK, + buffer->startingBlock); + + StorageUtl_WriteDWord( + currentProperty, + OFFSET_PS_SIZE, + buffer->size.u.LowPart); + + writeSuccessful = BlockChainStream_WriteAt(This->rootBlockChain, + offsetInPropSet, + PROPSET_BLOCK_SIZE, + currentProperty, + &bytesWritten); + return writeSuccessful; +} + +BOOL StorageImpl_ReadBigBlock( + StorageImpl* This, + ULONG blockIndex, + void* buffer) +{ + void* bigBlockBuffer; + + bigBlockBuffer = StorageImpl_GetROBigBlock(This, blockIndex); + + if (bigBlockBuffer!=0) + { + memcpy(buffer, bigBlockBuffer, This->bigBlockSize); + + StorageImpl_ReleaseBigBlock(This, bigBlockBuffer); + + return TRUE; + } + + return FALSE; +} + +BOOL StorageImpl_WriteBigBlock( + StorageImpl* This, + ULONG blockIndex, + void* buffer) +{ + void* bigBlockBuffer; + + bigBlockBuffer = StorageImpl_GetBigBlock(This, blockIndex); + + if (bigBlockBuffer!=0) + { + memcpy(bigBlockBuffer, buffer, This->bigBlockSize); + + StorageImpl_ReleaseBigBlock(This, bigBlockBuffer); + + return TRUE; + } + + return FALSE; +} + +void* StorageImpl_GetROBigBlock( + StorageImpl* This, + ULONG blockIndex) +{ + return BIGBLOCKFILE_GetROBigBlock(This->bigBlockFile, blockIndex); +} + +void* StorageImpl_GetBigBlock( + StorageImpl* This, + ULONG blockIndex) +{ + return BIGBLOCKFILE_GetBigBlock(This->bigBlockFile, blockIndex); +} + +void StorageImpl_ReleaseBigBlock( + StorageImpl* This, + void* pBigBlock) +{ + BIGBLOCKFILE_ReleaseBigBlock(This->bigBlockFile, pBigBlock); +} + +/****************************************************************************** + * Storage32Impl_SmallBlocksToBigBlocks + * + * This method will convert a small block chain to a big block chain. + * The small block chain will be destroyed. + */ +BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks( + StorageImpl* This, + SmallBlockChainStream** ppsbChain) +{ + ULONG bbHeadOfChain = BLOCK_END_OF_CHAIN; + ULARGE_INTEGER size, offset; + ULONG cbRead, cbWritten, cbTotalRead, cbTotalWritten; + ULONG propertyIndex; + BOOL successRead, successWrite; + StgProperty chainProperty; + BYTE *buffer; + BlockChainStream *bbTempChain = NULL; + BlockChainStream *bigBlockChain = NULL; + + /* + * Create a temporary big block chain that doesn't have + * an associated property. This temporary chain will be + * used to copy data from small blocks to big blocks. + */ + bbTempChain = BlockChainStream_Construct(This, + &bbHeadOfChain, + PROPERTY_NULL); + + /* + * Grow the big block chain. + */ + size = SmallBlockChainStream_GetSize(*ppsbChain); + BlockChainStream_SetSize(bbTempChain, size); + + /* + * Copy the contents of the small block chain to the big block chain + * by small block size increments. + */ + offset.u.LowPart = 0; + offset.u.HighPart = 0; + cbTotalRead = 0; + cbTotalWritten = 0; + + buffer = (BYTE *) HeapAlloc(GetProcessHeap(),0,DEF_SMALL_BLOCK_SIZE); + do + { + successRead = SmallBlockChainStream_ReadAt(*ppsbChain, + offset, + DEF_SMALL_BLOCK_SIZE, + buffer, + &cbRead); + cbTotalRead += cbRead; + + successWrite = BlockChainStream_WriteAt(bbTempChain, + offset, + cbRead, + buffer, + &cbWritten); + cbTotalWritten += cbWritten; + + offset.u.LowPart += This->smallBlockSize; + + } while (successRead && successWrite); + HeapFree(GetProcessHeap(),0,buffer); + + assert(cbTotalRead == cbTotalWritten); + + /* + * Destroy the small block chain. + */ + propertyIndex = (*ppsbChain)->ownerPropertyIndex; + size.u.HighPart = 0; + size.u.LowPart = 0; + SmallBlockChainStream_SetSize(*ppsbChain, size); + SmallBlockChainStream_Destroy(*ppsbChain); + *ppsbChain = 0; + + /* + * Change the property information. This chain is now a big block chain + * and it doesn't reside in the small blocks chain anymore. + */ + StorageImpl_ReadProperty(This, propertyIndex, &chainProperty); + + chainProperty.startingBlock = bbHeadOfChain; + + StorageImpl_WriteProperty(This, propertyIndex, &chainProperty); + + /* + * Destroy the temporary propertyless big block chain. + * Create a new big block chain associated with this property. + */ + BlockChainStream_Destroy(bbTempChain); + bigBlockChain = BlockChainStream_Construct(This, + NULL, + propertyIndex); + + return bigBlockChain; +} + +/****************************************************************************** +** Storage32InternalImpl implementation +*/ + +StorageInternalImpl* StorageInternalImpl_Construct( + StorageImpl* ancestorStorage, + ULONG rootPropertyIndex) +{ + StorageInternalImpl* newStorage; + + /* + * Allocate space for the new storage object + */ + newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageInternalImpl)); + + if (newStorage!=0) + { + memset(newStorage, 0, sizeof(StorageInternalImpl)); + + /* + * Initialize the virtual function table. + */ + ICOM_VTBL(newStorage) = &Storage32InternalImpl_Vtbl; + newStorage->v_destructor = &StorageInternalImpl_Destroy; + + /* + * Keep the ancestor storage pointer and nail a reference to it. + */ + newStorage->ancestorStorage = ancestorStorage; + StorageBaseImpl_AddRef((IStorage*)(newStorage->ancestorStorage)); + + /* + * Keep the index of the root property set for this storage, + */ + newStorage->rootPropertySetIndex = rootPropertyIndex; + + return newStorage; + } + + return 0; +} + +void StorageInternalImpl_Destroy( + StorageInternalImpl* This) +{ + StorageBaseImpl_Release((IStorage*)This->ancestorStorage); + HeapFree(GetProcessHeap(), 0, This); +} + +/****************************************************************************** +** +** Storage32InternalImpl_Commit +** +** The non-root storages cannot be opened in transacted mode thus this function +** does nothing. +*/ +HRESULT WINAPI StorageInternalImpl_Commit( + IStorage* iface, + DWORD grfCommitFlags) /* [in] */ +{ + return S_OK; +} + +/****************************************************************************** +** +** Storage32InternalImpl_Revert +** +** The non-root storages cannot be opened in transacted mode thus this function +** does nothing. +*/ +HRESULT WINAPI StorageInternalImpl_Revert( + IStorage* iface) +{ + return S_OK; +} + +/****************************************************************************** +** IEnumSTATSTGImpl implementation +*/ + +IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct( + StorageImpl* parentStorage, + ULONG firstPropertyNode) +{ + IEnumSTATSTGImpl* newEnumeration; + + newEnumeration = HeapAlloc(GetProcessHeap(), 0, sizeof(IEnumSTATSTGImpl)); + + if (newEnumeration!=0) + { + /* + * Set-up the virtual function table and reference count. + */ + ICOM_VTBL(newEnumeration) = &IEnumSTATSTGImpl_Vtbl; + newEnumeration->ref = 0; + + /* + * We want to nail-down the reference to the storage in case the + * enumeration out-lives the storage in the client application. + */ + newEnumeration->parentStorage = parentStorage; + IStorage_AddRef((IStorage*)newEnumeration->parentStorage); + + newEnumeration->firstPropertyNode = firstPropertyNode; + + /* + * Initialize the search stack + */ + newEnumeration->stackSize = 0; + newEnumeration->stackMaxSize = ENUMSTATSGT_SIZE_INCREMENT; + newEnumeration->stackToVisit = + HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG)*ENUMSTATSGT_SIZE_INCREMENT); + + /* + * Make sure the current node of the iterator is the first one. + */ + IEnumSTATSTGImpl_Reset((IEnumSTATSTG*)newEnumeration); + } + + return newEnumeration; +} + +void IEnumSTATSTGImpl_Destroy(IEnumSTATSTGImpl* This) +{ + IStorage_Release((IStorage*)This->parentStorage); + HeapFree(GetProcessHeap(), 0, This->stackToVisit); + HeapFree(GetProcessHeap(), 0, This); +} + +HRESULT WINAPI IEnumSTATSTGImpl_QueryInterface( + IEnumSTATSTG* iface, + REFIID riid, + void** ppvObject) +{ + IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; + + /* + * Perform a sanity check on the parameters. + */ + if (ppvObject==0) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = (IEnumSTATSTG*)This; + } + else if (memcmp(&IID_IStorage, riid, sizeof(IID_IEnumSTATSTG)) == 0) + { + *ppvObject = (IEnumSTATSTG*)This; + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + return E_NOINTERFACE; + + /* + * Query Interface always increases the reference count by one when it is + * successful + */ + IEnumSTATSTGImpl_AddRef((IEnumSTATSTG*)This); + + return S_OK; +} + +ULONG WINAPI IEnumSTATSTGImpl_AddRef( + IEnumSTATSTG* iface) +{ + IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; + + This->ref++; + return This->ref; +} + +ULONG WINAPI IEnumSTATSTGImpl_Release( + IEnumSTATSTG* iface) +{ + IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; + + ULONG newRef; + + This->ref--; + newRef = This->ref; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (newRef==0) + { + IEnumSTATSTGImpl_Destroy(This); + } + + return newRef;; +} + +HRESULT WINAPI IEnumSTATSTGImpl_Next( + IEnumSTATSTG* iface, + ULONG celt, + STATSTG* rgelt, + ULONG* pceltFetched) +{ + IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; + + StgProperty currentProperty; + STATSTG* currentReturnStruct = rgelt; + ULONG objectFetched = 0; + ULONG currentSearchNode; + + /* + * Perform a sanity check on the parameters. + */ + if ( (rgelt==0) || ( (celt!=1) && (pceltFetched==0) ) ) + return E_INVALIDARG; + + /* + * To avoid the special case, get another pointer to a ULONG value if + * the caller didn't supply one. + */ + if (pceltFetched==0) + pceltFetched = &objectFetched; + + /* + * Start the iteration, we will iterate until we hit the end of the + * linked list or until we hit the number of items to iterate through + */ + *pceltFetched = 0; + + /* + * Start with the node at the top of the stack. + */ + currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); + + while ( ( *pceltFetched < celt) && + ( currentSearchNode!=PROPERTY_NULL) ) + { + /* + * Remove the top node from the stack + */ + IEnumSTATSTGImpl_PopSearchNode(This, TRUE); + + /* + * Read the property from the storage. + */ + StorageImpl_ReadProperty(This->parentStorage, + currentSearchNode, + ¤tProperty); + + /* + * Copy the information to the return buffer. + */ + StorageUtl_CopyPropertyToSTATSTG(currentReturnStruct, + ¤tProperty, + STATFLAG_DEFAULT); + + /* + * Step to the next item in the iteration + */ + (*pceltFetched)++; + currentReturnStruct++; + + /* + * Push the next search node in the search stack. + */ + IEnumSTATSTGImpl_PushSearchNode(This, currentProperty.nextProperty); + + /* + * continue the iteration. + */ + currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); + } + + if (*pceltFetched == celt) + return S_OK; + + return S_FALSE; +} + + +HRESULT WINAPI IEnumSTATSTGImpl_Skip( + IEnumSTATSTG* iface, + ULONG celt) +{ + IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; + + StgProperty currentProperty; + ULONG objectFetched = 0; + ULONG currentSearchNode; + + /* + * Start with the node at the top of the stack. + */ + currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); + + while ( (objectFetched < celt) && + (currentSearchNode!=PROPERTY_NULL) ) + { + /* + * Remove the top node from the stack + */ + IEnumSTATSTGImpl_PopSearchNode(This, TRUE); + + /* + * Read the property from the storage. + */ + StorageImpl_ReadProperty(This->parentStorage, + currentSearchNode, + ¤tProperty); + + /* + * Step to the next item in the iteration + */ + objectFetched++; + + /* + * Push the next search node in the search stack. + */ + IEnumSTATSTGImpl_PushSearchNode(This, currentProperty.nextProperty); + + /* + * continue the iteration. + */ + currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); + } + + if (objectFetched == celt) + return S_OK; + + return S_FALSE; +} + +HRESULT WINAPI IEnumSTATSTGImpl_Reset( + IEnumSTATSTG* iface) +{ + IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; + + StgProperty rootProperty; + BOOL readSuccessful; + + /* + * Re-initialize the search stack to an empty stack + */ + This->stackSize = 0; + + /* + * Read the root property from the storage. + */ + readSuccessful = StorageImpl_ReadProperty( + This->parentStorage, + This->firstPropertyNode, + &rootProperty); + + if (readSuccessful) + { + assert(rootProperty.sizeOfNameString!=0); + + /* + * Push the search node in the search stack. + */ + IEnumSTATSTGImpl_PushSearchNode(This, rootProperty.dirProperty); + } + + return S_OK; +} + +HRESULT WINAPI IEnumSTATSTGImpl_Clone( + IEnumSTATSTG* iface, + IEnumSTATSTG** ppenum) +{ + IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface; + + IEnumSTATSTGImpl* newClone; + + /* + * Perform a sanity check on the parameters. + */ + if (ppenum==0) + return E_INVALIDARG; + + newClone = IEnumSTATSTGImpl_Construct(This->parentStorage, + This->firstPropertyNode); + + + /* + * The new clone enumeration must point to the same current node as + * the ole one. + */ + newClone->stackSize = This->stackSize ; + newClone->stackMaxSize = This->stackMaxSize ; + newClone->stackToVisit = + HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG) * newClone->stackMaxSize); + + memcpy( + newClone->stackToVisit, + This->stackToVisit, + sizeof(ULONG) * newClone->stackSize); + + *ppenum = (IEnumSTATSTG*)newClone; + + /* + * Don't forget to nail down a reference to the clone before + * returning it. + */ + IEnumSTATSTGImpl_AddRef(*ppenum); + + return S_OK; +} + +INT IEnumSTATSTGImpl_FindParentProperty( + IEnumSTATSTGImpl *This, + ULONG childProperty, + StgProperty *currentProperty, + ULONG *thisNodeId) +{ + ULONG currentSearchNode; + ULONG foundNode; + + /* + * To avoid the special case, get another pointer to a ULONG value if + * the caller didn't supply one. + */ + if (thisNodeId==0) + thisNodeId = &foundNode; + + /* + * Start with the node at the top of the stack. + */ + currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); + + + while (currentSearchNode!=PROPERTY_NULL) + { + /* + * Store the current node in the returned parameters + */ + *thisNodeId = currentSearchNode; + + /* + * Remove the top node from the stack + */ + IEnumSTATSTGImpl_PopSearchNode(This, TRUE); + + /* + * Read the property from the storage. + */ + StorageImpl_ReadProperty( + This->parentStorage, + currentSearchNode, + currentProperty); + + if (currentProperty->previousProperty == childProperty) + return PROPERTY_RELATION_PREVIOUS; + + else if (currentProperty->nextProperty == childProperty) + return PROPERTY_RELATION_NEXT; + + else if (currentProperty->dirProperty == childProperty) + return PROPERTY_RELATION_DIR; + + /* + * Push the next search node in the search stack. + */ + IEnumSTATSTGImpl_PushSearchNode(This, currentProperty->nextProperty); + + /* + * continue the iteration. + */ + currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); + } + + return PROPERTY_NULL; +} + +ULONG IEnumSTATSTGImpl_FindProperty( + IEnumSTATSTGImpl* This, + const OLECHAR* lpszPropName, + StgProperty* currentProperty) +{ + ULONG currentSearchNode; + + /* + * Start with the node at the top of the stack. + */ + currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); + + while (currentSearchNode!=PROPERTY_NULL) + { + /* + * Remove the top node from the stack + */ + IEnumSTATSTGImpl_PopSearchNode(This, TRUE); + + /* + * Read the property from the storage. + */ + StorageImpl_ReadProperty(This->parentStorage, + currentSearchNode, + currentProperty); + + if ( propertyNameCmp( + (OLECHAR*)currentProperty->name, + (OLECHAR*)lpszPropName) == 0) + return currentSearchNode; + + /* + * Push the next search node in the search stack. + */ + IEnumSTATSTGImpl_PushSearchNode(This, currentProperty->nextProperty); + + /* + * continue the iteration. + */ + currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); + } + + return PROPERTY_NULL; +} + +void IEnumSTATSTGImpl_PushSearchNode( + IEnumSTATSTGImpl* This, + ULONG nodeToPush) +{ + StgProperty rootProperty; + BOOL readSuccessful; + + /* + * First, make sure we're not trying to push an unexisting node. + */ + if (nodeToPush==PROPERTY_NULL) + return; + + /* + * First push the node to the stack + */ + if (This->stackSize == This->stackMaxSize) + { + This->stackMaxSize += ENUMSTATSGT_SIZE_INCREMENT; + + This->stackToVisit = HeapReAlloc( + GetProcessHeap(), + 0, + This->stackToVisit, + sizeof(ULONG) * This->stackMaxSize); + } + + This->stackToVisit[This->stackSize] = nodeToPush; + This->stackSize++; + + /* + * Read the root property from the storage. + */ + readSuccessful = StorageImpl_ReadProperty( + This->parentStorage, + nodeToPush, + &rootProperty); + + if (readSuccessful) + { + assert(rootProperty.sizeOfNameString!=0); + + /* + * Push the previous search node in the search stack. + */ + IEnumSTATSTGImpl_PushSearchNode(This, rootProperty.previousProperty); + } +} + +ULONG IEnumSTATSTGImpl_PopSearchNode( + IEnumSTATSTGImpl* This, + BOOL remove) +{ + ULONG topNode; + + if (This->stackSize == 0) + return PROPERTY_NULL; + + topNode = This->stackToVisit[This->stackSize-1]; + + if (remove) + This->stackSize--; + + return topNode; +} + +/****************************************************************************** +** StorageUtl implementation +*/ + +void StorageUtl_ReadWord(void* buffer, ULONG offset, WORD* value) +{ + memcpy(value, (BYTE*)buffer+offset, sizeof(WORD)); +} + +void StorageUtl_WriteWord(void* buffer, ULONG offset, WORD value) +{ + memcpy((BYTE*)buffer+offset, &value, sizeof(WORD)); +} + +void StorageUtl_ReadDWord(void* buffer, ULONG offset, DWORD* value) +{ + memcpy(value, (BYTE*)buffer+offset, sizeof(DWORD)); +} + +void StorageUtl_WriteDWord(void* buffer, ULONG offset, DWORD value) +{ + memcpy((BYTE*)buffer+offset, &value, sizeof(DWORD)); +} + +void StorageUtl_ReadGUID(void* buffer, ULONG offset, GUID* value) +{ + StorageUtl_ReadDWord(buffer, offset, &(value->Data1)); + StorageUtl_ReadWord(buffer, offset+4, &(value->Data2)); + StorageUtl_ReadWord(buffer, offset+6, &(value->Data3)); + + memcpy(value->Data4, (BYTE*)buffer+offset+8, sizeof(value->Data4)); +} + +void StorageUtl_WriteGUID(void* buffer, ULONG offset, GUID* value) +{ + StorageUtl_WriteDWord(buffer, offset, value->Data1); + StorageUtl_WriteWord(buffer, offset+4, value->Data2); + StorageUtl_WriteWord(buffer, offset+6, value->Data3); + + memcpy((BYTE*)buffer+offset+8, value->Data4, sizeof(value->Data4)); +} + +void StorageUtl_CopyPropertyToSTATSTG( + STATSTG* destination, + StgProperty* source, + int statFlags) +{ + /* + * The copy of the string occurs only when the flag is not set + */ + if ((statFlags & STATFLAG_NONAME) != 0) + { + destination->pwcsName = 0; + } + else + { + destination->pwcsName = + CoTaskMemAlloc((lstrlenW(source->name)+1)*sizeof(WCHAR)); + + lstrcpyW((LPWSTR)destination->pwcsName, source->name); + } + + switch (source->propertyType) + { + case PROPTYPE_STORAGE: + case PROPTYPE_ROOT: + destination->type = STGTY_STORAGE; + break; + case PROPTYPE_STREAM: + destination->type = STGTY_STREAM; + break; + default: + destination->type = STGTY_STREAM; + break; + } + + destination->cbSize = source->size; +/* + currentReturnStruct->mtime = {0}; TODO + currentReturnStruct->ctime = {0}; + currentReturnStruct->atime = {0}; +*/ + destination->grfMode = 0; + destination->grfLocksSupported = 0; + destination->clsid = source->propertyUniqueID; + destination->grfStateBits = 0; + destination->reserved = 0; +} + +/****************************************************************************** +** BlockChainStream implementation +*/ + +BlockChainStream* BlockChainStream_Construct( + StorageImpl* parentStorage, + ULONG* headOfStreamPlaceHolder, + ULONG propertyIndex) +{ + BlockChainStream* newStream; + ULONG blockIndex; + + newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(BlockChainStream)); + + newStream->parentStorage = parentStorage; + newStream->headOfStreamPlaceHolder = headOfStreamPlaceHolder; + newStream->ownerPropertyIndex = propertyIndex; + newStream->lastBlockNoInSequence = 0xFFFFFFFF; + newStream->tailIndex = BLOCK_END_OF_CHAIN; + newStream->numBlocks = 0; + + blockIndex = BlockChainStream_GetHeadOfChain(newStream); + + while (blockIndex != BLOCK_END_OF_CHAIN) + { + newStream->numBlocks++; + newStream->tailIndex = blockIndex; + + blockIndex = StorageImpl_GetNextBlockInChain( + parentStorage, + blockIndex); + } + + return newStream; +} + +void BlockChainStream_Destroy(BlockChainStream* This) +{ + HeapFree(GetProcessHeap(), 0, This); +} + +/****************************************************************************** + * BlockChainStream_GetHeadOfChain + * + * Returns the head of this stream chain. + * Some special chains don't have properties, their heads are kept in + * This->headOfStreamPlaceHolder. + * + */ +ULONG BlockChainStream_GetHeadOfChain(BlockChainStream* This) +{ + StgProperty chainProperty; + BOOL readSuccessful; + + if (This->headOfStreamPlaceHolder != 0) + return *(This->headOfStreamPlaceHolder); + + if (This->ownerPropertyIndex != PROPERTY_NULL) + { + readSuccessful = StorageImpl_ReadProperty( + This->parentStorage, + This->ownerPropertyIndex, + &chainProperty); + + if (readSuccessful) + { + return chainProperty.startingBlock; + } + } + + return BLOCK_END_OF_CHAIN; +} + +/****************************************************************************** + * BlockChainStream_GetCount + * + * Returns the number of blocks that comprises this chain. + * This is not the size of the stream as the last block may not be full! + * + */ +ULONG BlockChainStream_GetCount(BlockChainStream* This) +{ + ULONG blockIndex; + ULONG count = 0; + + blockIndex = BlockChainStream_GetHeadOfChain(This); + + while (blockIndex != BLOCK_END_OF_CHAIN) + { + count++; + + blockIndex = StorageImpl_GetNextBlockInChain( + This->parentStorage, + blockIndex); + } + + return count; +} + +/****************************************************************************** + * BlockChainStream_ReadAt + * + * Reads a specified number of bytes from this chain at the specified offset. + * bytesRead may be NULL. + * Failure will be returned if the specified number of bytes has not been read. + */ +BOOL BlockChainStream_ReadAt(BlockChainStream* This, + ULARGE_INTEGER offset, + ULONG size, + void* buffer, + ULONG* bytesRead) +{ + ULONG blockNoInSequence = offset.u.LowPart / This->parentStorage->bigBlockSize; + ULONG offsetInBlock = offset.u.LowPart % This->parentStorage->bigBlockSize; + ULONG bytesToReadInBuffer; + ULONG blockIndex; + BYTE* bufferWalker; + BYTE* bigBlockBuffer; + + /* + * Find the first block in the stream that contains part of the buffer. + */ + if ( (This->lastBlockNoInSequence == 0xFFFFFFFF) || + (This->lastBlockNoInSequenceIndex == BLOCK_END_OF_CHAIN) || + (blockNoInSequence < This->lastBlockNoInSequence) ) + { + blockIndex = BlockChainStream_GetHeadOfChain(This); + This->lastBlockNoInSequence = blockNoInSequence; + } + else + { + ULONG temp = blockNoInSequence; + + blockIndex = This->lastBlockNoInSequenceIndex; + blockNoInSequence -= This->lastBlockNoInSequence; + This->lastBlockNoInSequence = temp; + } + + while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) + { + blockIndex = + StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); + + blockNoInSequence--; + } + + This->lastBlockNoInSequenceIndex = blockIndex; + + /* + * Start reading the buffer. + */ + *bytesRead = 0; + bufferWalker = buffer; + + while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) ) + { + /* + * Calculate how many bytes we can copy from this big block. + */ + bytesToReadInBuffer = + min(This->parentStorage->bigBlockSize - offsetInBlock, size); + + /* + * Copy those bytes to the buffer + */ + bigBlockBuffer = + StorageImpl_GetROBigBlock(This->parentStorage, blockIndex); + + memcpy(bufferWalker, bigBlockBuffer + offsetInBlock, bytesToReadInBuffer); + + StorageImpl_ReleaseBigBlock(This->parentStorage, bigBlockBuffer); + + /* + * Step to the next big block. + */ + blockIndex = + StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); + + bufferWalker += bytesToReadInBuffer; + size -= bytesToReadInBuffer; + *bytesRead += bytesToReadInBuffer; + offsetInBlock = 0; /* There is no offset on the next block */ + + } + + return (size == 0); +} + +/****************************************************************************** + * BlockChainStream_WriteAt + * + * Writes the specified number of bytes to this chain at the specified offset. + * bytesWritten may be NULL. + * Will fail if not all specified number of bytes have been written. + */ +BOOL BlockChainStream_WriteAt(BlockChainStream* This, + ULARGE_INTEGER offset, + ULONG size, + const void* buffer, + ULONG* bytesWritten) +{ + ULONG blockNoInSequence = offset.u.LowPart / This->parentStorage->bigBlockSize; + ULONG offsetInBlock = offset.u.LowPart % This->parentStorage->bigBlockSize; + ULONG bytesToWrite; + ULONG blockIndex; + BYTE* bufferWalker; + BYTE* bigBlockBuffer; + + /* + * Find the first block in the stream that contains part of the buffer. + */ + if ( (This->lastBlockNoInSequence == 0xFFFFFFFF) || + (This->lastBlockNoInSequenceIndex == BLOCK_END_OF_CHAIN) || + (blockNoInSequence < This->lastBlockNoInSequence) ) + { + blockIndex = BlockChainStream_GetHeadOfChain(This); + This->lastBlockNoInSequence = blockNoInSequence; + } + else + { + ULONG temp = blockNoInSequence; + + blockIndex = This->lastBlockNoInSequenceIndex; + blockNoInSequence -= This->lastBlockNoInSequence; + This->lastBlockNoInSequence = temp; + } + + while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) + { + blockIndex = + StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); + + blockNoInSequence--; + } + + This->lastBlockNoInSequenceIndex = blockIndex; + + /* + * Here, I'm casting away the constness on the buffer variable + * This is OK since we don't intend to modify that buffer. + */ + *bytesWritten = 0; + bufferWalker = (BYTE*)buffer; + + while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) ) + { + /* + * Calculate how many bytes we can copy from this big block. + */ + bytesToWrite = + min(This->parentStorage->bigBlockSize - offsetInBlock, size); + + /* + * Copy those bytes to the buffer + */ + bigBlockBuffer = StorageImpl_GetBigBlock(This->parentStorage, blockIndex); + + memcpy(bigBlockBuffer + offsetInBlock, bufferWalker, bytesToWrite); + + StorageImpl_ReleaseBigBlock(This->parentStorage, bigBlockBuffer); + + /* + * Step to the next big block. + */ + blockIndex = + StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); + + bufferWalker += bytesToWrite; + size -= bytesToWrite; + *bytesWritten += bytesToWrite; + offsetInBlock = 0; /* There is no offset on the next block */ + } + + return (size == 0); +} + +/****************************************************************************** + * BlockChainStream_Shrink + * + * Shrinks this chain in the big block depot. + */ +BOOL BlockChainStream_Shrink(BlockChainStream* This, + ULARGE_INTEGER newSize) +{ + ULONG blockIndex, extraBlock; + ULONG numBlocks; + ULONG count = 1; + + /* + * Reset the last accessed block cache. + */ + This->lastBlockNoInSequence = 0xFFFFFFFF; + This->lastBlockNoInSequenceIndex = BLOCK_END_OF_CHAIN; + + /* + * Figure out how many blocks are needed to contain the new size + */ + numBlocks = newSize.u.LowPart / This->parentStorage->bigBlockSize; + + if ((newSize.u.LowPart % This->parentStorage->bigBlockSize) != 0) + numBlocks++; + + blockIndex = BlockChainStream_GetHeadOfChain(This); + + /* + * Go to the new end of chain + */ + while (count < numBlocks) + { + blockIndex = + StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); + + count++; + } + + /* Get the next block before marking the new end */ + extraBlock = + StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); + + /* Mark the new end of chain */ + StorageImpl_SetNextBlockInChain( + This->parentStorage, + blockIndex, + BLOCK_END_OF_CHAIN); + + This->tailIndex = blockIndex; + This->numBlocks = numBlocks; + + /* + * Mark the extra blocks as free + */ + while (extraBlock != BLOCK_END_OF_CHAIN) + { + blockIndex = + StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock); + + StorageImpl_FreeBigBlock(This->parentStorage, extraBlock); + extraBlock = blockIndex; + } + + return TRUE; +} + +/****************************************************************************** + * BlockChainStream_Enlarge + * + * Grows this chain in the big block depot. + */ +BOOL BlockChainStream_Enlarge(BlockChainStream* This, + ULARGE_INTEGER newSize) +{ + ULONG blockIndex, currentBlock; + ULONG newNumBlocks; + ULONG oldNumBlocks = 0; + + blockIndex = BlockChainStream_GetHeadOfChain(This); + + /* + * Empty chain. Create the head. + */ + if (blockIndex == BLOCK_END_OF_CHAIN) + { + blockIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage); + StorageImpl_SetNextBlockInChain(This->parentStorage, + blockIndex, + BLOCK_END_OF_CHAIN); + + if (This->headOfStreamPlaceHolder != 0) + { + *(This->headOfStreamPlaceHolder) = blockIndex; + } + else + { + StgProperty chainProp; + assert(This->ownerPropertyIndex != PROPERTY_NULL); + + StorageImpl_ReadProperty( + This->parentStorage, + This->ownerPropertyIndex, + &chainProp); + + chainProp.startingBlock = blockIndex; + + StorageImpl_WriteProperty( + This->parentStorage, + This->ownerPropertyIndex, + &chainProp); + } + + This->tailIndex = blockIndex; + This->numBlocks = 1; + } + + /* + * Figure out how many blocks are needed to contain this stream + */ + newNumBlocks = newSize.u.LowPart / This->parentStorage->bigBlockSize; + + if ((newSize.u.LowPart % This->parentStorage->bigBlockSize) != 0) + newNumBlocks++; + + /* + * Go to the current end of chain + */ + if (This->tailIndex == BLOCK_END_OF_CHAIN) + { + currentBlock = blockIndex; + + while (blockIndex != BLOCK_END_OF_CHAIN) + { + This->numBlocks++; + currentBlock = blockIndex; + + blockIndex = + StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock); + } + + This->tailIndex = currentBlock; + } + + currentBlock = This->tailIndex; + oldNumBlocks = This->numBlocks; + + /* + * Add new blocks to the chain + */ + if (oldNumBlocks < newNumBlocks) + { + while (oldNumBlocks < newNumBlocks) + { + blockIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage); + + StorageImpl_SetNextBlockInChain( + This->parentStorage, + currentBlock, + blockIndex); + + StorageImpl_SetNextBlockInChain( + This->parentStorage, + blockIndex, + BLOCK_END_OF_CHAIN); + + currentBlock = blockIndex; + oldNumBlocks++; + } + + This->tailIndex = blockIndex; + This->numBlocks = newNumBlocks; + } + + return TRUE; +} + +/****************************************************************************** + * BlockChainStream_SetSize + * + * Sets the size of this stream. The big block depot will be updated. + * The file will grow if we grow the chain. + * + * TODO: Free the actual blocks in the file when we shrink the chain. + * Currently, the blocks are still in the file. So the file size + * doesn't shrink even if we shrink streams. + */ +BOOL BlockChainStream_SetSize( + BlockChainStream* This, + ULARGE_INTEGER newSize) +{ + ULARGE_INTEGER size = BlockChainStream_GetSize(This); + + if (newSize.u.LowPart == size.u.LowPart) + return TRUE; + + if (newSize.u.LowPart < size.u.LowPart) + { + BlockChainStream_Shrink(This, newSize); + } + else + { + ULARGE_INTEGER fileSize = + BIGBLOCKFILE_GetSize(This->parentStorage->bigBlockFile); + + ULONG diff = newSize.u.LowPart - size.u.LowPart; + + /* + * Make sure the file stays a multiple of blocksize + */ + if ((diff % This->parentStorage->bigBlockSize) != 0) + diff += (This->parentStorage->bigBlockSize - + (diff % This->parentStorage->bigBlockSize) ); + + fileSize.u.LowPart += diff; + BIGBLOCKFILE_SetSize(This->parentStorage->bigBlockFile, fileSize); + + BlockChainStream_Enlarge(This, newSize); + } + + return TRUE; +} + +/****************************************************************************** + * BlockChainStream_GetSize + * + * Returns the size of this chain. + * Will return the block count if this chain doesn't have a property. + */ +ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This) +{ + StgProperty chainProperty; + + if(This->headOfStreamPlaceHolder == NULL) + { + /* + * This chain is a data stream read the property and return + * the appropriate size + */ + StorageImpl_ReadProperty( + This->parentStorage, + This->ownerPropertyIndex, + &chainProperty); + + return chainProperty.size; + } + else + { + /* + * this chain is a chain that does not have a property, figure out the + * size by making the product number of used blocks times the + * size of them + */ + ULARGE_INTEGER result; + result.u.HighPart = 0; + + result.u.LowPart = + BlockChainStream_GetCount(This) * + This->parentStorage->bigBlockSize; + + return result; + } +} + +/****************************************************************************** +** SmallBlockChainStream implementation +*/ + +SmallBlockChainStream* SmallBlockChainStream_Construct( + StorageImpl* parentStorage, + ULONG propertyIndex) +{ + SmallBlockChainStream* newStream; + + newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(SmallBlockChainStream)); + + newStream->parentStorage = parentStorage; + newStream->ownerPropertyIndex = propertyIndex; + + return newStream; +} + +void SmallBlockChainStream_Destroy( + SmallBlockChainStream* This) +{ + HeapFree(GetProcessHeap(), 0, This); +} + +/****************************************************************************** + * SmallBlockChainStream_GetHeadOfChain + * + * Returns the head of this chain of small blocks. + */ +ULONG SmallBlockChainStream_GetHeadOfChain( + SmallBlockChainStream* This) +{ + StgProperty chainProperty; + BOOL readSuccessful; + + if (This->ownerPropertyIndex) + { + readSuccessful = StorageImpl_ReadProperty( + This->parentStorage, + This->ownerPropertyIndex, + &chainProperty); + + if (readSuccessful) + { + return chainProperty.startingBlock; + } + + } + + return BLOCK_END_OF_CHAIN; +} + +/****************************************************************************** + * SmallBlockChainStream_GetNextBlockInChain + * + * Returns the index of the next small block in this chain. + * + * Return Values: + * - BLOCK_END_OF_CHAIN: end of this chain + * - BLOCK_UNUSED: small block 'blockIndex' is free + */ +ULONG SmallBlockChainStream_GetNextBlockInChain( + SmallBlockChainStream* This, + ULONG blockIndex) +{ + ULARGE_INTEGER offsetOfBlockInDepot; + DWORD buffer; + ULONG nextBlockInChain = BLOCK_END_OF_CHAIN; + ULONG bytesRead; + BOOL success; + + offsetOfBlockInDepot.u.HighPart = 0; + offsetOfBlockInDepot.u.LowPart = blockIndex * sizeof(ULONG); + + /* + * Read those bytes in the buffer from the small block file. + */ + success = BlockChainStream_ReadAt( + This->parentStorage->smallBlockDepotChain, + offsetOfBlockInDepot, + sizeof(DWORD), + &buffer, + &bytesRead); + + if (success) + { + StorageUtl_ReadDWord(&buffer, 0, &nextBlockInChain); + } + + return nextBlockInChain; +} + +/****************************************************************************** + * SmallBlockChainStream_SetNextBlockInChain + * + * Writes the index of the next block of the specified block in the small + * block depot. + * To set the end of chain use BLOCK_END_OF_CHAIN as nextBlock. + * To flag a block as free use BLOCK_UNUSED as nextBlock. + */ +void SmallBlockChainStream_SetNextBlockInChain( + SmallBlockChainStream* This, + ULONG blockIndex, + ULONG nextBlock) +{ + ULARGE_INTEGER offsetOfBlockInDepot; + DWORD buffer; + ULONG bytesWritten; + + offsetOfBlockInDepot.u.HighPart = 0; + offsetOfBlockInDepot.u.LowPart = blockIndex * sizeof(ULONG); + + StorageUtl_WriteDWord(&buffer, 0, nextBlock); + + /* + * Read those bytes in the buffer from the small block file. + */ + BlockChainStream_WriteAt( + This->parentStorage->smallBlockDepotChain, + offsetOfBlockInDepot, + sizeof(DWORD), + &buffer, + &bytesWritten); +} + +/****************************************************************************** + * SmallBlockChainStream_FreeBlock + * + * Flag small block 'blockIndex' as free in the small block depot. + */ +void SmallBlockChainStream_FreeBlock( + SmallBlockChainStream* This, + ULONG blockIndex) +{ + SmallBlockChainStream_SetNextBlockInChain(This, blockIndex, BLOCK_UNUSED); +} + +/****************************************************************************** + * SmallBlockChainStream_GetNextFreeBlock + * + * Returns the index of a free small block. The small block depot will be + * enlarged if necessary. The small block chain will also be enlarged if + * necessary. + */ +ULONG SmallBlockChainStream_GetNextFreeBlock( + SmallBlockChainStream* This) +{ + ULARGE_INTEGER offsetOfBlockInDepot; + DWORD buffer; + ULONG bytesRead; + ULONG blockIndex = 0; + ULONG nextBlockIndex = BLOCK_END_OF_CHAIN; + BOOL success = TRUE; + ULONG smallBlocksPerBigBlock; + + offsetOfBlockInDepot.u.HighPart = 0; + + /* + * Scan the small block depot for a free block + */ + while (nextBlockIndex != BLOCK_UNUSED) + { + offsetOfBlockInDepot.u.LowPart = blockIndex * sizeof(ULONG); + + success = BlockChainStream_ReadAt( + This->parentStorage->smallBlockDepotChain, + offsetOfBlockInDepot, + sizeof(DWORD), + &buffer, + &bytesRead); + + /* + * If we run out of space for the small block depot, enlarge it + */ + if (success) + { + StorageUtl_ReadDWord(&buffer, 0, &nextBlockIndex); + + if (nextBlockIndex != BLOCK_UNUSED) + blockIndex++; + } + else + { + ULONG count = + BlockChainStream_GetCount(This->parentStorage->smallBlockDepotChain); + + ULONG sbdIndex = This->parentStorage->smallBlockDepotStart; + ULONG nextBlock, newsbdIndex; + BYTE* smallBlockDepot; + + nextBlock = sbdIndex; + while (nextBlock != BLOCK_END_OF_CHAIN) + { + sbdIndex = nextBlock; + nextBlock = + StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex); + } + + newsbdIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage); + if (sbdIndex != BLOCK_END_OF_CHAIN) + StorageImpl_SetNextBlockInChain( + This->parentStorage, + sbdIndex, + newsbdIndex); + + StorageImpl_SetNextBlockInChain( + This->parentStorage, + newsbdIndex, + BLOCK_END_OF_CHAIN); + + /* + * Initialize all the small blocks to free + */ + smallBlockDepot = + StorageImpl_GetBigBlock(This->parentStorage, newsbdIndex); + + memset(smallBlockDepot, BLOCK_UNUSED, This->parentStorage->bigBlockSize); + StorageImpl_ReleaseBigBlock(This->parentStorage, smallBlockDepot); + + if (count == 0) + { + /* + * We have just created the small block depot. + */ + StgProperty rootProp; + ULONG sbStartIndex; + + /* + * Save it in the header + */ + This->parentStorage->smallBlockDepotStart = newsbdIndex; + StorageImpl_SaveFileHeader(This->parentStorage); + + /* + * And allocate the first big block that will contain small blocks + */ + sbStartIndex = + StorageImpl_GetNextFreeBigBlock(This->parentStorage); + + StorageImpl_SetNextBlockInChain( + This->parentStorage, + sbStartIndex, + BLOCK_END_OF_CHAIN); + + StorageImpl_ReadProperty( + This->parentStorage, + This->parentStorage->rootPropertySetIndex, + &rootProp); + + rootProp.startingBlock = sbStartIndex; + rootProp.size.u.HighPart = 0; + rootProp.size.u.LowPart = This->parentStorage->bigBlockSize; + + StorageImpl_WriteProperty( + This->parentStorage, + This->parentStorage->rootPropertySetIndex, + &rootProp); + } + } + } + + smallBlocksPerBigBlock = + This->parentStorage->bigBlockSize / This->parentStorage->smallBlockSize; + + /* + * Verify if we have to allocate big blocks to contain small blocks + */ + if (blockIndex % smallBlocksPerBigBlock == 0) + { + StgProperty rootProp; + ULONG blocksRequired = (blockIndex / smallBlocksPerBigBlock) + 1; + + StorageImpl_ReadProperty( + This->parentStorage, + This->parentStorage->rootPropertySetIndex, + &rootProp); + + if (rootProp.size.u.LowPart < + (blocksRequired * This->parentStorage->bigBlockSize)) + { + rootProp.size.u.LowPart += This->parentStorage->bigBlockSize; + + BlockChainStream_SetSize( + This->parentStorage->smallBlockRootChain, + rootProp.size); + + StorageImpl_WriteProperty( + This->parentStorage, + This->parentStorage->rootPropertySetIndex, + &rootProp); + } + } + + return blockIndex; +} + +/****************************************************************************** + * SmallBlockChainStream_ReadAt + * + * Reads a specified number of bytes from this chain at the specified offset. + * bytesRead may be NULL. + * Failure will be returned if the specified number of bytes has not been read. + */ +BOOL SmallBlockChainStream_ReadAt( + SmallBlockChainStream* This, + ULARGE_INTEGER offset, + ULONG size, + void* buffer, + ULONG* bytesRead) +{ + ULARGE_INTEGER offsetInBigBlockFile; + ULONG blockNoInSequence = + offset.u.LowPart / This->parentStorage->smallBlockSize; + + ULONG offsetInBlock = offset.u.LowPart % This->parentStorage->smallBlockSize; + ULONG bytesToReadInBuffer; + ULONG blockIndex; + ULONG bytesReadFromBigBlockFile; + BYTE* bufferWalker; + + /* + * This should never happen on a small block file. + */ + assert(offset.u.HighPart==0); + + /* + * Find the first block in the stream that contains part of the buffer. + */ + blockIndex = SmallBlockChainStream_GetHeadOfChain(This); + + while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) + { + blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + + blockNoInSequence--; + } + + /* + * Start reading the buffer. + */ + *bytesRead = 0; + bufferWalker = buffer; + + while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) ) + { + /* + * Calculate how many bytes we can copy from this small block. + */ + bytesToReadInBuffer = + min(This->parentStorage->smallBlockSize - offsetInBlock, size); + + /* + * Calculate the offset of the small block in the small block file. + */ + offsetInBigBlockFile.u.HighPart = 0; + offsetInBigBlockFile.u.LowPart = + blockIndex * This->parentStorage->smallBlockSize; + + offsetInBigBlockFile.u.LowPart += offsetInBlock; + + /* + * Read those bytes in the buffer from the small block file. + */ + BlockChainStream_ReadAt(This->parentStorage->smallBlockRootChain, + offsetInBigBlockFile, + bytesToReadInBuffer, + bufferWalker, + &bytesReadFromBigBlockFile); + + assert(bytesReadFromBigBlockFile == bytesToReadInBuffer); + + /* + * Step to the next big block. + */ + blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + bufferWalker += bytesToReadInBuffer; + size -= bytesToReadInBuffer; + *bytesRead += bytesToReadInBuffer; + offsetInBlock = 0; /* There is no offset on the next block */ + } + + return (size == 0); +} + +/****************************************************************************** + * SmallBlockChainStream_WriteAt + * + * Writes the specified number of bytes to this chain at the specified offset. + * bytesWritten may be NULL. + * Will fail if not all specified number of bytes have been written. + */ +BOOL SmallBlockChainStream_WriteAt( + SmallBlockChainStream* This, + ULARGE_INTEGER offset, + ULONG size, + const void* buffer, + ULONG* bytesWritten) +{ + ULARGE_INTEGER offsetInBigBlockFile; + ULONG blockNoInSequence = + offset.u.LowPart / This->parentStorage->smallBlockSize; + + ULONG offsetInBlock = offset.u.LowPart % This->parentStorage->smallBlockSize; + ULONG bytesToWriteInBuffer; + ULONG blockIndex; + ULONG bytesWrittenFromBigBlockFile; + BYTE* bufferWalker; + + /* + * This should never happen on a small block file. + */ + assert(offset.u.HighPart==0); + + /* + * Find the first block in the stream that contains part of the buffer. + */ + blockIndex = SmallBlockChainStream_GetHeadOfChain(This); + + while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) + { + blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + + blockNoInSequence--; + } + + /* + * Start writing the buffer. + * + * Here, I'm casting away the constness on the buffer variable + * This is OK since we don't intend to modify that buffer. + */ + *bytesWritten = 0; + bufferWalker = (BYTE*)buffer; + while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) ) + { + /* + * Calculate how many bytes we can copy to this small block. + */ + bytesToWriteInBuffer = + min(This->parentStorage->smallBlockSize - offsetInBlock, size); + + /* + * Calculate the offset of the small block in the small block file. + */ + offsetInBigBlockFile.u.HighPart = 0; + offsetInBigBlockFile.u.LowPart = + blockIndex * This->parentStorage->smallBlockSize; + + offsetInBigBlockFile.u.LowPart += offsetInBlock; + + /* + * Write those bytes in the buffer to the small block file. + */ + BlockChainStream_WriteAt(This->parentStorage->smallBlockRootChain, + offsetInBigBlockFile, + bytesToWriteInBuffer, + bufferWalker, + &bytesWrittenFromBigBlockFile); + + assert(bytesWrittenFromBigBlockFile == bytesToWriteInBuffer); + + /* + * Step to the next big block. + */ + blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + bufferWalker += bytesToWriteInBuffer; + size -= bytesToWriteInBuffer; + *bytesWritten += bytesToWriteInBuffer; + offsetInBlock = 0; /* There is no offset on the next block */ + } + + return (size == 0); +} + +/****************************************************************************** + * SmallBlockChainStream_Shrink + * + * Shrinks this chain in the small block depot. + */ +BOOL SmallBlockChainStream_Shrink( + SmallBlockChainStream* This, + ULARGE_INTEGER newSize) +{ + ULONG blockIndex, extraBlock; + ULONG numBlocks; + ULONG count = 0; + + numBlocks = newSize.u.LowPart / This->parentStorage->smallBlockSize; + + if ((newSize.u.LowPart % This->parentStorage->smallBlockSize) != 0) + numBlocks++; + + blockIndex = SmallBlockChainStream_GetHeadOfChain(This); + + /* + * Go to the new end of chain + */ + while (count < numBlocks) + { + blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + count++; + } + + /* + * If the count is 0, we have a special case, the head of the chain was + * just freed. + */ + if (count == 0) + { + StgProperty chainProp; + + StorageImpl_ReadProperty(This->parentStorage, + This->ownerPropertyIndex, + &chainProp); + + chainProp.startingBlock = BLOCK_END_OF_CHAIN; + + StorageImpl_WriteProperty(This->parentStorage, + This->ownerPropertyIndex, + &chainProp); + + /* + * We start freeing the chain at the head block. + */ + extraBlock = blockIndex; + } + else + { + /* Get the next block before marking the new end */ + extraBlock = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + + /* Mark the new end of chain */ + SmallBlockChainStream_SetNextBlockInChain( + This, + blockIndex, + BLOCK_END_OF_CHAIN); + } + + /* + * Mark the extra blocks as free + */ + while (extraBlock != BLOCK_END_OF_CHAIN) + { + blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, extraBlock); + SmallBlockChainStream_FreeBlock(This, extraBlock); + extraBlock = blockIndex; + } + + return TRUE; +} + +/****************************************************************************** + * SmallBlockChainStream_Enlarge + * + * Grows this chain in the small block depot. + */ +BOOL SmallBlockChainStream_Enlarge( + SmallBlockChainStream* This, + ULARGE_INTEGER newSize) +{ + ULONG blockIndex, currentBlock; + ULONG newNumBlocks; + ULONG oldNumBlocks = 0; + + blockIndex = SmallBlockChainStream_GetHeadOfChain(This); + + /* + * Empty chain + */ + if (blockIndex == BLOCK_END_OF_CHAIN) + { + + StgProperty chainProp; + + StorageImpl_ReadProperty(This->parentStorage, This->ownerPropertyIndex, + &chainProp); + + chainProp.startingBlock = SmallBlockChainStream_GetNextFreeBlock(This); + + StorageImpl_WriteProperty(This->parentStorage, This->ownerPropertyIndex, + &chainProp); + + blockIndex = chainProp.startingBlock; + SmallBlockChainStream_SetNextBlockInChain( + This, + blockIndex, + BLOCK_END_OF_CHAIN); + } + + currentBlock = blockIndex; + + /* + * Figure out how many blocks are needed to contain this stream + */ + newNumBlocks = newSize.u.LowPart / This->parentStorage->smallBlockSize; + + if ((newSize.u.LowPart % This->parentStorage->smallBlockSize) != 0) + newNumBlocks++; + + /* + * Go to the current end of chain + */ + while (blockIndex != BLOCK_END_OF_CHAIN) + { + oldNumBlocks++; + currentBlock = blockIndex; + blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, currentBlock); + } + + /* + * Add new blocks to the chain + */ + while (oldNumBlocks < newNumBlocks) + { + blockIndex = SmallBlockChainStream_GetNextFreeBlock(This); + SmallBlockChainStream_SetNextBlockInChain(This, currentBlock, blockIndex); + + SmallBlockChainStream_SetNextBlockInChain( + This, + blockIndex, + BLOCK_END_OF_CHAIN); + + currentBlock = blockIndex; + oldNumBlocks++; + } + + return TRUE; +} + +/****************************************************************************** + * SmallBlockChainStream_GetCount + * + * Returns the number of blocks that comprises this chain. + * This is not the size of this chain as the last block may not be full! + */ +ULONG SmallBlockChainStream_GetCount(SmallBlockChainStream* This) +{ + ULONG blockIndex; + ULONG count = 0; + + blockIndex = SmallBlockChainStream_GetHeadOfChain(This); + + while (blockIndex != BLOCK_END_OF_CHAIN) + { + count++; + + blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); + } + + return count; +} + +/****************************************************************************** + * SmallBlockChainStream_SetSize + * + * Sets the size of this stream. + * The file will grow if we grow the chain. + * + * TODO: Free the actual blocks in the file when we shrink the chain. + * Currently, the blocks are still in the file. So the file size + * doesn't shrink even if we shrink streams. + */ +BOOL SmallBlockChainStream_SetSize( + SmallBlockChainStream* This, + ULARGE_INTEGER newSize) +{ + ULARGE_INTEGER size = SmallBlockChainStream_GetSize(This); + + if (newSize.u.LowPart == size.u.LowPart) + return TRUE; + + if (newSize.u.LowPart < size.u.LowPart) + { + SmallBlockChainStream_Shrink(This, newSize); + } + else + { + SmallBlockChainStream_Enlarge(This, newSize); + } + + return TRUE; +} + +/****************************************************************************** + * SmallBlockChainStream_GetSize + * + * Returns the size of this chain. + */ +ULARGE_INTEGER SmallBlockChainStream_GetSize(SmallBlockChainStream* This) +{ + StgProperty chainProperty; + + StorageImpl_ReadProperty( + This->parentStorage, + This->ownerPropertyIndex, + &chainProperty); + + return chainProperty.size; +} + +/****************************************************************************** + * StgCreateDocfile [OLE32.144] + */ +HRESULT WINAPI StgCreateDocfile( + LPCOLESTR pwcsName, + DWORD grfMode, + DWORD reserved, + IStorage **ppstgOpen) +{ + StorageImpl* newStorage = 0; + HANDLE hFile = INVALID_HANDLE_VALUE; + HRESULT hr = S_OK; + DWORD shareMode; + DWORD accessMode; + DWORD creationMode; + DWORD fileAttributes; + WCHAR tempFileName[MAX_PATH]; + + Print(MAX_TRACE, ("(%S, %lx, %ld, %p)\n", + pwcsName, grfMode, + reserved, ppstgOpen)); + + /* + * Validate the parameters + */ + if (ppstgOpen == 0) + return STG_E_INVALIDPOINTER; + + /* + * Validate the STGM flags + */ + if ( FAILED( validateSTGM(grfMode) )) + return STG_E_INVALIDFLAG; + + /* + * Generate a unique name. + */ + if (pwcsName == 0) + { + WCHAR tempPath[MAX_PATH]; + WCHAR prefix[] = { 'S', 'T', 'O', 0 }; + + if (!(grfMode & STGM_SHARE_EXCLUSIVE)) + return STG_E_INVALIDFLAG; + if (!(grfMode & (STGM_WRITE|STGM_READWRITE))) + return STG_E_INVALIDFLAG; + + memset(tempPath, 0, sizeof(tempPath)); + memset(tempFileName, 0, sizeof(tempFileName)); + + if ((GetTempPathW(MAX_PATH, tempPath)) == 0 ) + tempPath[0] = '.'; + + if (GetTempFileNameW(tempPath, prefix, 0, tempFileName) != 0) + pwcsName = tempFileName; + else + return STG_E_INSUFFICIENTMEMORY; + + creationMode = TRUNCATE_EXISTING; + } + else + { + creationMode = GetCreationModeFromSTGM(grfMode); + } + + /* + * Interpret the STGM value grfMode + */ + shareMode = GetShareModeFromSTGM(grfMode); + accessMode = GetAccessModeFromSTGM(grfMode); + + if (grfMode & STGM_DELETEONRELEASE) + fileAttributes = FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_DELETE_ON_CLOSE; + else + fileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS; + + if (grfMode & STGM_TRANSACTED) + UNIMPLEMENTED; + + /* + * Initialize the "out" parameter. + */ + *ppstgOpen = 0; + + hFile = CreateFileW(pwcsName, + accessMode, + shareMode, + NULL, + creationMode, + fileAttributes, + 0); + + if (hFile == INVALID_HANDLE_VALUE) + { + return E_FAIL; + } + + /* + * Allocate and initialize the new IStorage32object. + */ + newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); + + if (newStorage == 0) + return STG_E_INSUFFICIENTMEMORY; + + hr = StorageImpl_Construct( + newStorage, + hFile, + NULL, + grfMode, + TRUE, + TRUE); + + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, newStorage); + return hr; + } + + /* + * Get an "out" pointer for the caller. + */ + hr = StorageBaseImpl_QueryInterface( + (IStorage*)newStorage, + (REFIID)&IID_IStorage, + (void**)ppstgOpen); + + return hr; +} + +/****************************************************************************** + * StgOpenStorage [OLE32.148] + */ +HRESULT WINAPI StgOpenStorage( + const OLECHAR *pwcsName, + IStorage *pstgPriority, + DWORD grfMode, + SNB snbExclude, + DWORD reserved, + IStorage **ppstgOpen) +{ + StorageImpl* newStorage = 0; + HRESULT hr = S_OK; + HANDLE hFile = 0; + DWORD shareMode; + DWORD accessMode; + + Print(MAX_TRACE, ("(%S, %p, %lx, %p, %ld, %p)\n", + pwcsName, pstgPriority, grfMode, + snbExclude, reserved, ppstgOpen)); + + /* + * Perform a sanity check + */ + if (( pwcsName == 0) || (ppstgOpen == 0) ) + return STG_E_INVALIDPOINTER; + + /* + * Validate the STGM flags + */ + if ( FAILED( validateSTGM(grfMode) )) + return STG_E_INVALIDFLAG; + + /* + * Interpret the STGM value grfMode + */ + shareMode = GetShareModeFromSTGM(grfMode); + accessMode = GetAccessModeFromSTGM(grfMode); + + /* + * Initialize the "out" parameter. + */ + *ppstgOpen = 0; + + hFile = CreateFileW( pwcsName, + accessMode, + shareMode, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, + 0); + + + if (hFile==INVALID_HANDLE_VALUE) + { + HRESULT hr = E_FAIL; + DWORD last_error = GetLastError(); + + switch (last_error) + { + case ERROR_FILE_NOT_FOUND: + hr = STG_E_FILENOTFOUND; + break; + + case ERROR_PATH_NOT_FOUND: + hr = STG_E_PATHNOTFOUND; + break; + + case ERROR_ACCESS_DENIED: + case ERROR_WRITE_PROTECT: + hr = STG_E_ACCESSDENIED; + break; + + case ERROR_SHARING_VIOLATION: + hr = STG_E_SHAREVIOLATION; + break; + + default: + hr = E_FAIL; + } + + return hr; + } + + /* + * Allocate and initialize the new IStorage32object. + */ + newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); + + if (newStorage == 0) + return STG_E_INSUFFICIENTMEMORY; + + hr = StorageImpl_Construct( + newStorage, + hFile, + NULL, + grfMode, + TRUE, + FALSE); + + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, newStorage); + /* + * According to the docs if the file is not a storage, return STG_E_FILEALREADYEXISTS + */ + if(hr == STG_E_INVALIDHEADER) + return STG_E_FILEALREADYEXISTS; + return hr; + } + + /* + * Get an "out" pointer for the caller. + */ + hr = StorageBaseImpl_QueryInterface( + (IStorage*)newStorage, + (REFIID)&IID_IStorage, + (void**)ppstgOpen); + + return hr; +} + +/****************************************************************************** + * StgCreateDocfileOnILockBytes [OLE32.145] + */ +HRESULT WINAPI StgCreateDocfileOnILockBytes( + ILockBytes *plkbyt, + DWORD grfMode, + DWORD reserved, + IStorage** ppstgOpen) +{ + StorageImpl* newStorage = 0; + HRESULT hr = S_OK; + + /* + * Validate the parameters + */ + if ((ppstgOpen == 0) || (plkbyt == 0)) + return STG_E_INVALIDPOINTER; + + /* + * Allocate and initialize the new IStorage object. + */ + newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); + + if (newStorage == 0) + return STG_E_INSUFFICIENTMEMORY; + + hr = StorageImpl_Construct( + newStorage, + 0, + plkbyt, + grfMode, + FALSE, + TRUE); + + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, newStorage); + return hr; + } + + /* + * Get an "out" pointer for the caller. + */ + hr = StorageBaseImpl_QueryInterface( + (IStorage*)newStorage, + (REFIID)&IID_IStorage, + (void**)ppstgOpen); + + return hr; +} + +/****************************************************************************** + * StgOpenStorageOnILockBytes [OLE32.149] + */ +HRESULT WINAPI StgOpenStorageOnILockBytes( + ILockBytes *plkbyt, + IStorage *pstgPriority, + DWORD grfMode, + SNB snbExclude, + DWORD reserved, + IStorage **ppstgOpen) +{ + StorageImpl* newStorage = 0; + HRESULT hr = S_OK; + + /* + * Perform a sanity check + */ + if ((plkbyt == 0) || (ppstgOpen == 0)) + return STG_E_INVALIDPOINTER; + + /* + * Validate the STGM flags + */ + if ( FAILED( validateSTGM(grfMode) )) + return STG_E_INVALIDFLAG; + + /* + * Initialize the "out" parameter. + */ + *ppstgOpen = 0; + + /* + * Allocate and initialize the new IStorage object. + */ + newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); + + if (newStorage == 0) + return STG_E_INSUFFICIENTMEMORY; + + hr = StorageImpl_Construct( + newStorage, + 0, + plkbyt, + grfMode, + FALSE, + FALSE); + + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, newStorage); + return hr; + } + + /* + * Get an "out" pointer for the caller. + */ + hr = StorageBaseImpl_QueryInterface( + (IStorage*)newStorage, + (REFIID)&IID_IStorage, + (void**)ppstgOpen); + + return hr; +} + +/****************************************************************************** + * StgSetTimes [ole32.150] + * + * + */ +HRESULT WINAPI StgSetTimes(WCHAR * str, FILETIME * a, FILETIME * b, FILETIME *c ) +{ + + UNIMPLEMENTED; + return FALSE; +} + +/****************************************************************************** + * StgIsStorageILockBytes [OLE32.147] + * + * Determines if the ILockBytes contains a storage object. + */ +HRESULT WINAPI StgIsStorageILockBytes(ILockBytes *plkbyt) +{ + BYTE sig[8]; + ULARGE_INTEGER offset; + + offset.u.HighPart = 0; + offset.u.LowPart = 0; + + ILockBytes_ReadAt(plkbyt, offset, sig, sizeof(sig), NULL); + + if (memcmp(sig, STORAGE_magic, sizeof(STORAGE_magic)) == 0) + return S_OK; + + return S_FALSE; +} + +/****************************************************************************** + * WriteClassStg [OLE32.158] + * + * This method will store the specified CLSID in the specified storage object + */ +HRESULT WINAPI WriteClassStg(IStorage* pStg, REFCLSID rclsid) +{ + HRESULT hRes; + + assert(pStg != 0); + + hRes = IStorage_SetClass(pStg, rclsid); + + return hRes; +} + +/*********************************************************************** + * ReadClassStg + * + * This method reads the CLSID previously written to a storage object with the WriteClassStg. + */ +HRESULT WINAPI ReadClassStg(IStorage *pstg,CLSID *pclsid){ + + STATSTG pstatstg; + HRESULT hRes; + + Print(MAX_TRACE, ("()\n")); + + if(pclsid==NULL) + return E_POINTER; + /* + * read a STATSTG structure (contains the clsid) from the storage + */ + hRes=IStorage_Stat(pstg,&pstatstg,STATFLAG_DEFAULT); + + if(SUCCEEDED(hRes)) + *pclsid=pstatstg.clsid; + + return hRes; +} + +/*********************************************************************** + * OleLoadFromStream + * + * This function loads an object from stream + */ +HRESULT WINAPI OleLoadFromStream(IStream *pStm,REFIID iidInterface,void** ppvObj) +{ + CLSID clsid; + HRESULT res; + LPPERSISTSTREAM xstm; + + Print(MAX_TRACE, ("(%p,%s,%p)\n",pStm,PRINT_GUID(iidInterface),ppvObj)); + + res=ReadClassStm(pStm,&clsid); + if (!SUCCEEDED(res)) + return res; + res=CoCreateInstance(&clsid,NULL,CLSCTX_INPROC_SERVER,iidInterface,ppvObj); + if (!SUCCEEDED(res)) + return res; + res=IUnknown_QueryInterface((IUnknown*)*ppvObj,&IID_IPersistStream,(LPVOID*)&xstm); + if (!SUCCEEDED(res)) { + IUnknown_Release((IUnknown*)*ppvObj); + return res; + } + res=IPersistStream_Load(xstm,pStm); + IPersistStream_Release(xstm); + /* FIXME: all refcounts ok at this point? I think they should be: + * pStm : unchanged + * ppvObj : 1 + * xstm : 0 (released) + */ + return res; +} + +/*********************************************************************** + * OleSaveToStream + * + * This function saves an object with the IPersistStream interface on it + * to the specified stream. + */ +HRESULT WINAPI OleSaveToStream(IPersistStream *pPStm,IStream *pStm) +{ + + CLSID clsid; + HRESULT res; + + Print(MAX_TRACE, ("(%p,%p)\n",pPStm,pStm)); + + res=IPersistStream_GetClassID(pPStm,&clsid); + + if (SUCCEEDED(res)){ + + res=WriteClassStm(pStm,&clsid); + + if (SUCCEEDED(res)) + + res=IPersistStream_Save(pPStm,pStm,TRUE); + } + + Print(MAX_TRACE, ("Finished Save\n")); + return res; +} + +/**************************************************************************** + * This method validate a STGM parameter that can contain the values below + * + * STGM_DIRECT 0x00000000 + * STGM_TRANSACTED 0x00010000 + * STGM_SIMPLE 0x08000000 + * + * STGM_READ 0x00000000 + * STGM_WRITE 0x00000001 + * STGM_READWRITE 0x00000002 + * + * STGM_SHARE_DENY_NONE 0x00000040 + * STGM_SHARE_DENY_READ 0x00000030 + * STGM_SHARE_DENY_WRITE 0x00000020 + * STGM_SHARE_EXCLUSIVE 0x00000010 + * + * STGM_PRIORITY 0x00040000 + * STGM_DELETEONRELEASE 0x04000000 + * + * STGM_CREATE 0x00001000 + * STGM_CONVERT 0x00020000 + * STGM_FAILIFTHERE 0x00000000 + * + * STGM_NOSCRATCH 0x00100000 + * STGM_NOSNAPSHOT 0x00200000 + */ +static HRESULT validateSTGM(DWORD stgm) +{ + BOOL bSTGM_TRANSACTED = ((stgm & STGM_TRANSACTED) == STGM_TRANSACTED); + BOOL bSTGM_SIMPLE = ((stgm & STGM_SIMPLE) == STGM_SIMPLE); + BOOL bSTGM_DIRECT = ! (bSTGM_TRANSACTED || bSTGM_SIMPLE); + + BOOL bSTGM_WRITE = ((stgm & STGM_WRITE) == STGM_WRITE); + BOOL bSTGM_READWRITE = ((stgm & STGM_READWRITE) == STGM_READWRITE); + BOOL bSTGM_READ = ! (bSTGM_WRITE || bSTGM_READWRITE); + + BOOL bSTGM_SHARE_DENY_NONE = + ((stgm & STGM_SHARE_DENY_NONE) == STGM_SHARE_DENY_NONE); + + BOOL bSTGM_SHARE_DENY_READ = + ((stgm & STGM_SHARE_DENY_READ) == STGM_SHARE_DENY_READ); + + BOOL bSTGM_SHARE_DENY_WRITE = + ((stgm & STGM_SHARE_DENY_WRITE) == STGM_SHARE_DENY_WRITE); + + BOOL bSTGM_SHARE_EXCLUSIVE = + ((stgm & STGM_SHARE_EXCLUSIVE) == STGM_SHARE_EXCLUSIVE); + + BOOL bSTGM_CREATE = ((stgm & STGM_CREATE) == STGM_CREATE); + BOOL bSTGM_CONVERT = ((stgm & STGM_CONVERT) == STGM_CONVERT); + + BOOL bSTGM_NOSCRATCH = ((stgm & STGM_NOSCRATCH) == STGM_NOSCRATCH); + BOOL bSTGM_NOSNAPSHOT = ((stgm & STGM_NOSNAPSHOT) == STGM_NOSNAPSHOT); + + /* + * STGM_DIRECT | STGM_TRANSACTED | STGM_SIMPLE + */ + if ( ! bSTGM_DIRECT ) + if( bSTGM_TRANSACTED && bSTGM_SIMPLE ) + return E_FAIL; + + /* + * STGM_WRITE | STGM_READWRITE | STGM_READ + */ + if ( ! bSTGM_READ ) + if( bSTGM_WRITE && bSTGM_READWRITE ) + return E_FAIL; + + /* + * STGM_SHARE_DENY_NONE | others + * (I assume here that DENY_READ implies DENY_WRITE) + */ + if ( bSTGM_SHARE_DENY_NONE ) + if ( bSTGM_SHARE_DENY_READ || + bSTGM_SHARE_DENY_WRITE || + bSTGM_SHARE_EXCLUSIVE) + return E_FAIL; + + /* + * STGM_CREATE | STGM_CONVERT + * if both are false, STGM_FAILIFTHERE is set to TRUE + */ + if ( bSTGM_CREATE && bSTGM_CONVERT ) + return E_FAIL; + + /* + * STGM_NOSCRATCH requires STGM_TRANSACTED + */ + if ( bSTGM_NOSCRATCH && ! bSTGM_TRANSACTED ) + return E_FAIL; + + /* + * STGM_NOSNAPSHOT requires STGM_TRANSACTED and + * not STGM_SHARE_EXCLUSIVE or STGM_SHARE_DENY_WRITE` + */ + if (bSTGM_NOSNAPSHOT) + { + if ( ! ( bSTGM_TRANSACTED && + !(bSTGM_SHARE_EXCLUSIVE || bSTGM_SHARE_DENY_WRITE)) ) + return E_FAIL; + } + + return S_OK; +} + +/**************************************************************************** + * GetShareModeFromSTGM + * + * This method will return a share mode flag from a STGM value. + * The STGM value is assumed valid. + */ +static DWORD GetShareModeFromSTGM(DWORD stgm) +{ + DWORD dwShareMode = 0; + BOOL bSTGM_SHARE_DENY_NONE = + ((stgm & STGM_SHARE_DENY_NONE) == STGM_SHARE_DENY_NONE); + + BOOL bSTGM_SHARE_DENY_READ = + ((stgm & STGM_SHARE_DENY_READ) == STGM_SHARE_DENY_READ); + + BOOL bSTGM_SHARE_DENY_WRITE = + ((stgm & STGM_SHARE_DENY_WRITE) == STGM_SHARE_DENY_WRITE); + + BOOL bSTGM_SHARE_EXCLUSIVE = + ((stgm & STGM_SHARE_EXCLUSIVE) == STGM_SHARE_EXCLUSIVE); + + if ((bSTGM_SHARE_EXCLUSIVE) || (bSTGM_SHARE_DENY_READ)) + dwShareMode = 0; + + if (bSTGM_SHARE_DENY_NONE) + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + + if (bSTGM_SHARE_DENY_WRITE) + dwShareMode = FILE_SHARE_READ; + + return dwShareMode; +} + +/**************************************************************************** + * GetAccessModeFromSTGM + * + * This method will return an access mode flag from a STGM value. + * The STGM value is assumed valid. + */ +static DWORD GetAccessModeFromSTGM(DWORD stgm) +{ + DWORD dwDesiredAccess = GENERIC_READ; + BOOL bSTGM_WRITE = ((stgm & STGM_WRITE) == STGM_WRITE); + BOOL bSTGM_READWRITE = ((stgm & STGM_READWRITE) == STGM_READWRITE); + BOOL bSTGM_READ = ! (bSTGM_WRITE || bSTGM_READWRITE); + + if (bSTGM_READ) + dwDesiredAccess = GENERIC_READ; + + if (bSTGM_WRITE) + dwDesiredAccess |= GENERIC_WRITE; + + if (bSTGM_READWRITE) + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + + return dwDesiredAccess; +} + +/**************************************************************************** + * GetCreationModeFromSTGM + * + * This method will return a creation mode flag from a STGM value. + * The STGM value is assumed valid. + */ +static DWORD GetCreationModeFromSTGM(DWORD stgm) +{ + if ( stgm & STGM_CREATE) + return CREATE_ALWAYS; + if (stgm & STGM_CONVERT) { + UNIMPLEMENTED; + return CREATE_NEW; + } + /* All other cases */ + if (stgm & ~ (STGM_CREATE|STGM_CONVERT)) + Print(MIN_TRACE, ("unhandled storage mode : 0x%08lx\n",stgm & ~ (STGM_CREATE|STGM_CONVERT))); + return CREATE_NEW; +} + + +/************************************************************************* + * OLECONVERT_LoadOLE10 [Internal] + * + * Loads the OLE10 STREAM to memory + * + * PARAMS + * pOleStream [I] The OLESTREAM + * pData [I] Data Structure for the OLESTREAM Data + * + * RETURNS + * Success: S_OK + * Failure: CONVERT10_E_OLESTREAM_GET for invalid Get + * CONVERT10_E_OLESTREAM_FMT if the OLEID is invalide + * + * NOTES + * This function is used by OleConvertOLESTREAMToIStorage only. + * + * Memory allocated for pData must be freed by the caller + */ +HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *pData, BOOL bStrem1) +{ + DWORD dwSize; + HRESULT hRes = S_OK; + int nTryCnt=0; + int max_try = 6; + + pData->pData = NULL; + pData->pstrOleObjFileName = (CHAR *) NULL; + + for( nTryCnt=0;nTryCnt < max_try; nTryCnt++) + { + /* Get the OleID */ + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwOleID), sizeof(pData->dwOleID)); + if(dwSize != sizeof(pData->dwOleID)) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + else if(pData->dwOleID != OLESTREAM_ID) + { + hRes = CONVERT10_E_OLESTREAM_FMT; + } + else + { + hRes = S_OK; + break; + } + } + + if(hRes == S_OK) + { + /* Get the TypeID...more info needed for this field */ + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwTypeID), sizeof(pData->dwTypeID)); + if(dwSize != sizeof(pData->dwTypeID)) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + } + if(hRes == S_OK) + { + if(pData->dwTypeID != 0) + { + /* Get the lenght of the OleTypeName */ + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *) &(pData->dwOleTypeNameLength), sizeof(pData->dwOleTypeNameLength)); + if(dwSize != sizeof(pData->dwOleTypeNameLength)) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + + if(hRes == S_OK) + { + if(pData->dwOleTypeNameLength > 0) + { + /* Get the OleTypeName */ + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)pData->strOleTypeName, pData->dwOleTypeNameLength); + if(dwSize != pData->dwOleTypeNameLength) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + } + } + if(bStrem1) + { + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwOleObjFileNameLength), sizeof(pData->dwOleObjFileNameLength)); + if(dwSize != sizeof(pData->dwOleObjFileNameLength)) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + if(hRes == S_OK) + { + if(pData->dwOleObjFileNameLength < 1) /* there is no file name exist */ + pData->dwOleObjFileNameLength = sizeof(pData->dwOleObjFileNameLength); + pData->pstrOleObjFileName = (CHAR *)malloc(pData->dwOleObjFileNameLength); + if(pData->pstrOleObjFileName) + { + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)(pData->pstrOleObjFileName),pData->dwOleObjFileNameLength); + if(dwSize != pData->dwOleObjFileNameLength) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + } + else + hRes = CONVERT10_E_OLESTREAM_GET; + } + } + else + { + /* Get the Width of the Metafile */ + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwMetaFileWidth), sizeof(pData->dwMetaFileWidth)); + if(dwSize != sizeof(pData->dwMetaFileWidth)) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + if(hRes == S_OK) + { + /* Get the Height of the Metafile */ + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwMetaFileHeight), sizeof(pData->dwMetaFileHeight)); + if(dwSize != sizeof(pData->dwMetaFileHeight)) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + } + } + if(hRes == S_OK) + { + /* Get the Lenght of the Data */ + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwDataLength), sizeof(pData->dwDataLength)); + if(dwSize != sizeof(pData->dwDataLength)) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + } + + if(hRes == S_OK) /* I don't know what is this 8 byts information is we have to figure out */ + { + if(!bStrem1) /* if it is a second OLE stream data */ + { + pData->dwDataLength -= 8; + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)(pData->strUnknown), sizeof(pData->strUnknown)); + if(dwSize != sizeof(pData->strUnknown)) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + } + } + if(hRes == S_OK) + { + if(pData->dwDataLength > 0) + { + pData->pData = (BYTE *)HeapAlloc(GetProcessHeap(),0,pData->dwDataLength); + + /* Get Data (ex. IStorage, Metafile, or BMP) */ + if(pData->pData) + { + dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)pData->pData, pData->dwDataLength); + if(dwSize != pData->dwDataLength) + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + } + else + { + hRes = CONVERT10_E_OLESTREAM_GET; + } + } + } + } + } + return hRes; +} + +/************************************************************************* + * OLECONVERT_SaveOLE10 [Internal] + * + * Saves the OLE10 STREAM From memory + * + * PARAMS + * pData [I] Data Structure for the OLESTREAM Data + * pOleStream [I] The OLESTREAM to save + * + * RETURNS + * Success: S_OK + * Failure: CONVERT10_E_OLESTREAM_PUT for invalid Put + * + * NOTES + * This function is used by OleConvertIStorageToOLESTREAM only. + * + */ +HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREAM pOleStream) +{ + DWORD dwSize; + HRESULT hRes = S_OK; + + + /* Set the OleID */ + dwSize = pOleStream->lpstbl->Put(pOleStream, (void *)&(pData->dwOleID), sizeof(pData->dwOleID)); + if(dwSize != sizeof(pData->dwOleID)) + { + hRes = CONVERT10_E_OLESTREAM_PUT; + } + + if(hRes == S_OK) + { + /* Set the TypeID */ + dwSize = pOleStream->lpstbl->Put(pOleStream, (void *)&(pData->dwTypeID), sizeof(pData->dwTypeID)); + if(dwSize != sizeof(pData->dwTypeID)) + { + hRes = CONVERT10_E_OLESTREAM_PUT; + } + } + + if(pData->dwOleID == OLESTREAM_ID && pData->dwTypeID != 0 && hRes == S_OK) + { + /* Set the Lenght of the OleTypeName */ + dwSize = pOleStream->lpstbl->Put(pOleStream, (void *)&(pData->dwOleTypeNameLength), sizeof(pData->dwOleTypeNameLength)); + if(dwSize != sizeof(pData->dwOleTypeNameLength)) + { + hRes = CONVERT10_E_OLESTREAM_PUT; + } + + if(hRes == S_OK) + { + if(pData->dwOleTypeNameLength > 0) + { + /* Set the OleTypeName */ + dwSize = pOleStream->lpstbl->Put(pOleStream, (void *) pData->strOleTypeName, pData->dwOleTypeNameLength); + if(dwSize != pData->dwOleTypeNameLength) + { + hRes = CONVERT10_E_OLESTREAM_PUT; + } + } + } + + if(hRes == S_OK) + { + /* Set the width of the Metafile */ + dwSize = pOleStream->lpstbl->Put(pOleStream, (void *)&(pData->dwMetaFileWidth), sizeof(pData->dwMetaFileWidth)); + if(dwSize != sizeof(pData->dwMetaFileWidth)) + { + hRes = CONVERT10_E_OLESTREAM_PUT; + } + } + + if(hRes == S_OK) + { + /* Set the height of the Metafile */ + dwSize = pOleStream->lpstbl->Put(pOleStream, (void *)&(pData->dwMetaFileHeight), sizeof(pData->dwMetaFileHeight)); + if(dwSize != sizeof(pData->dwMetaFileHeight)) + { + hRes = CONVERT10_E_OLESTREAM_PUT; + } + } + + if(hRes == S_OK) + { + /* Set the lenght of the Data */ + dwSize = pOleStream->lpstbl->Put(pOleStream, (void *)&(pData->dwDataLength), sizeof(pData->dwDataLength)); + if(dwSize != sizeof(pData->dwDataLength)) + { + hRes = CONVERT10_E_OLESTREAM_PUT; + } + } + + if(hRes == S_OK) + { + if(pData->dwDataLength > 0) + { + /* Set the Data (eg. IStorage, Metafile, Bitmap) */ + dwSize = pOleStream->lpstbl->Put(pOleStream, (void *) pData->pData, pData->dwDataLength); + if(dwSize != pData->dwDataLength) + { + hRes = CONVERT10_E_OLESTREAM_PUT; + } + } + } + } + return hRes; +} + +/************************************************************************* + * OLECONVERT_GetOLE20FromOLE10[Internal] + * + * This function copies OLE10 Data (the IStorage in the OLESTREAM) to disk, + * opens it, and copies the content to the dest IStorage for + * OleConvertOLESTREAMToIStorage + * + * + * PARAMS + * pDestStorage [I] The IStorage to copy the data to + * pBuffer [I] Buffer that contains the IStorage from the OLESTREAM + * nBufferLength [I] The size of the buffer + * + * RETURNS + * Nothing + * + * NOTES + * + * + */ +void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD nBufferLength) +{ + HRESULT hRes; + HANDLE hFile; + IStorage *pTempStorage; + DWORD dwNumOfBytesWritten; + WCHAR wstrTempDir[MAX_PATH], wstrTempFile[MAX_PATH]; + WCHAR wstrPrefix[] = {'s', 'i', 's', 0}; + + /* Create a temp File */ + GetTempPathW(MAX_PATH, wstrTempDir); + GetTempFileNameW(wstrTempDir, wstrPrefix, 0, wstrTempFile); + hFile = CreateFileW(wstrTempFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + + if(hFile != INVALID_HANDLE_VALUE) + { + /* Write IStorage Data to File */ + WriteFile(hFile, pBuffer, nBufferLength, &dwNumOfBytesWritten, NULL); + CloseHandle(hFile); + + /* Open and copy temp storage to the Dest Storage */ + hRes = StgOpenStorage(wstrTempFile, NULL, STGM_READ, NULL, 0, &pTempStorage); + if(hRes == S_OK) + { + hRes = StorageImpl_CopyTo(pTempStorage, 0, NULL, NULL, pDestStorage); + StorageBaseImpl_Release(pTempStorage); + } + DeleteFileW(wstrTempFile); + } +} + + +/************************************************************************* + * OLECONVERT_WriteOLE20ToBuffer [Internal] + * + * Saves the OLE10 STREAM From memory + * + * PARAMS + * pStorage [I] The Src IStorage to copy + * pData [I] The Dest Memory to write to. + * + * RETURNS + * The size in bytes allocated for pData + * + * NOTES + * Memory allocated for pData must be freed by the caller + * + * Used by OleConvertIStorageToOLESTREAM only. + * + */ +DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData) +{ + HANDLE hFile; + HRESULT hRes; + DWORD nDataLength = 0; + IStorage *pTempStorage; + WCHAR wstrTempDir[MAX_PATH], wstrTempFile[MAX_PATH]; + WCHAR wstrPrefix[] = {'s', 'i', 's', 0}; + + *pData = NULL; + + /* Create temp Storage */ + GetTempPathW(MAX_PATH, wstrTempDir); + GetTempFileNameW(wstrTempDir, wstrPrefix, 0, wstrTempFile); + hRes = StgCreateDocfile(wstrTempFile, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pTempStorage); + + if(hRes == S_OK) + { + /* Copy Src Storage to the Temp Storage */ + StorageImpl_CopyTo(pStorage, 0, NULL, NULL, pTempStorage); + StorageBaseImpl_Release(pTempStorage); + + /* Open Temp Storage as a file and copy to memory */ + hFile = CreateFileW(wstrTempFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if(hFile != INVALID_HANDLE_VALUE) + { + nDataLength = GetFileSize(hFile, NULL); + *pData = (BYTE *) HeapAlloc(GetProcessHeap(),0,nDataLength); + ReadFile(hFile, *pData, nDataLength, &nDataLength, 0); + CloseHandle(hFile); + } + DeleteFileW(wstrTempFile); + } + return nDataLength; +} + +/************************************************************************* + * OLECONVERT_CreateOleStream [Internal] + * + * Creates the "\001OLE" stream in the IStorage if neccessary. + * + * PARAMS + * pStorage [I] Dest storage to create the stream in + * + * RETURNS + * Nothing + * + * NOTES + * This function is used by OleConvertOLESTREAMToIStorage only. + * + * This stream is still unknown, MS Word seems to have extra data + * but since the data is stored in the OLESTREAM there should be + * no need to recreate the stream. If the stream is manually + * deleted it will create it with this default data. + * + */ +void OLECONVERT_CreateOleStream(LPSTORAGE pStorage) +{ + HRESULT hRes; + IStream *pStream; + WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; + BYTE pOleStreamHeader [] = + { + 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + + /* Create stream if not present */ + hRes = IStorage_CreateStream(pStorage, wstrStreamName, + STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); + + if(hRes == S_OK) + { + /* Write default Data */ + hRes = IStream_Write(pStream, pOleStreamHeader, sizeof(pOleStreamHeader), NULL); + IStream_Release(pStream); + } +} + + +/************************************************************************* + * OLECONVERT_CreateCompObjStream [Internal] + * + * Creates a "\001CompObj" is the destination IStorage if necessary. + * + * PARAMS + * pStorage [I] The dest IStorage to create the CompObj Stream + * if necessary. + * strOleTypeName [I] The ProgID + * + * RETURNS + * Success: S_OK + * Failure: REGDB_E_CLASSNOTREG if cannot reconstruct the stream + * + * NOTES + * This function is used by OleConvertOLESTREAMToIStorage only. + * + * The stream data is stored in the OLESTREAM and there should be + * no need to recreate the stream. If the stream is manually + * deleted it will attempt to create it by querying the registry. + * + * + */ +HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName) +{ + IStream *pStream; + HRESULT hStorageRes, hRes = S_OK; + OLECONVERT_ISTORAGE_COMPOBJ IStorageCompObj; + WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0}; + + BYTE pCompObjUnknown1[] = {0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; + BYTE pCompObjUnknown2[] = {0xF4, 0x39, 0xB2, 0x71}; + + /* Initialize the CompObj structure */ + memset(&IStorageCompObj, 0, sizeof(IStorageCompObj)); + memcpy(&(IStorageCompObj.byUnknown1), pCompObjUnknown1, sizeof(pCompObjUnknown1)); + memcpy(&(IStorageCompObj.byUnknown2), pCompObjUnknown2, sizeof(pCompObjUnknown2)); + + + /* Create a CompObj stream if it doesn't exist */ + hStorageRes = IStorage_CreateStream(pStorage, wstrStreamName, + STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); + if(hStorageRes == S_OK) + { + /* copy the OleTypeName to the compobj struct */ + IStorageCompObj.dwOleTypeNameLength = strlen(strOleTypeName)+1; + strcpy(IStorageCompObj.strOleTypeName, strOleTypeName); + + /* copy the OleTypeName to the compobj struct */ + /* Note: in the test made, these were Identical */ + IStorageCompObj.dwProgIDNameLength = strlen(strOleTypeName)+1; + strcpy(IStorageCompObj.strProgIDName, strOleTypeName); + + /* Get the CLSID */ + hRes = CLSIDFromProgID16(IStorageCompObj.strProgIDName, &(IStorageCompObj.clsid)); + + if(hRes == S_OK) + { + HKEY hKey; + LONG hErr; + /* Get the CLSID Default Name from the Registry */ + hErr = RegOpenKeyA(HKEY_CLASSES_ROOT, IStorageCompObj.strProgIDName, &hKey); + if(hErr == ERROR_SUCCESS) + { + char strTemp[OLESTREAM_MAX_STR_LEN]; + IStorageCompObj.dwCLSIDNameLength = OLESTREAM_MAX_STR_LEN; + hErr = RegQueryValueA(hKey, NULL, strTemp, &(IStorageCompObj.dwCLSIDNameLength)); + if(hErr == ERROR_SUCCESS) + { + strcpy(IStorageCompObj.strCLSIDName, strTemp); + } + RegCloseKey(hKey); + } + } + + /* Write CompObj Structure to stream */ + hRes = IStream_Write(pStream, IStorageCompObj.byUnknown1, sizeof(IStorageCompObj.byUnknown1), NULL); + + WriteClassStm(pStream,&(IStorageCompObj.clsid)); + + hRes = IStream_Write(pStream, &(IStorageCompObj.dwCLSIDNameLength), sizeof(IStorageCompObj.dwCLSIDNameLength), NULL); + if(IStorageCompObj.dwCLSIDNameLength > 0) + { + hRes = IStream_Write(pStream, IStorageCompObj.strCLSIDName, IStorageCompObj.dwCLSIDNameLength, NULL); + } + hRes = IStream_Write(pStream, &(IStorageCompObj.dwOleTypeNameLength) , sizeof(IStorageCompObj.dwOleTypeNameLength), NULL); + if(IStorageCompObj.dwOleTypeNameLength > 0) + { + hRes = IStream_Write(pStream, IStorageCompObj.strOleTypeName , IStorageCompObj.dwOleTypeNameLength, NULL); + } + hRes = IStream_Write(pStream, &(IStorageCompObj.dwProgIDNameLength) , sizeof(IStorageCompObj.dwProgIDNameLength), NULL); + if(IStorageCompObj.dwProgIDNameLength > 0) + { + hRes = IStream_Write(pStream, IStorageCompObj.strProgIDName , IStorageCompObj.dwProgIDNameLength, NULL); + } + hRes = IStream_Write(pStream, IStorageCompObj.byUnknown2 , sizeof(IStorageCompObj.byUnknown2), NULL); + IStream_Release(pStream); + } + return hRes; +} + + +/************************************************************************* + * OLECONVERT_CreateOlePresStream[Internal] + * + * Creates the "\002OlePres000" Stream with the Metafile data + * + * PARAMS + * pStorage [I] The dest IStorage to create \002OLEPres000 stream in. + * dwExtentX [I] Width of the Metafile + * dwExtentY [I] Height of the Metafile + * pData [I] Metafile data + * dwDataLength [I] Size of the Metafile data + * + * RETURNS + * Success: S_OK + * Failure: CONVERT10_E_OLESTREAM_PUT for invalid Put + * + * NOTES + * This function is used by OleConvertOLESTREAMToIStorage only. + * + */ +void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX, DWORD dwExtentY , BYTE *pData, DWORD dwDataLength) +{ + HRESULT hRes; + IStream *pStream; + WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0}; + BYTE pOlePresStreamHeader [] = + { + 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + + BYTE pOlePresStreamHeaderEmpty [] = + { + 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + + /* Create the OlePres000 Stream */ + hRes = IStorage_CreateStream(pStorage, wstrStreamName, + STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); + + if(hRes == S_OK) + { + DWORD nHeaderSize; + OLECONVERT_ISTORAGE_OLEPRES OlePres; + + memset(&OlePres, 0, sizeof(OlePres)); + /* Do we have any metafile data to save */ + if(dwDataLength > 0) + { + memcpy(OlePres.byUnknown1, pOlePresStreamHeader, sizeof(pOlePresStreamHeader)); + nHeaderSize = sizeof(pOlePresStreamHeader); + } + else + { + memcpy(OlePres.byUnknown1, pOlePresStreamHeaderEmpty, sizeof(pOlePresStreamHeaderEmpty)); + nHeaderSize = sizeof(pOlePresStreamHeaderEmpty); + } + /* Set width and height of the metafile */ + OlePres.dwExtentX = dwExtentX; + OlePres.dwExtentY = -dwExtentY; + + /* Set Data and Lenght */ + if(dwDataLength > sizeof(METAFILEPICT16)) + { + OlePres.dwSize = dwDataLength - sizeof(METAFILEPICT16); + OlePres.pData = &(pData[8]); + } + /* Save OlePres000 Data to Stream */ + hRes = IStream_Write(pStream, OlePres.byUnknown1, nHeaderSize, NULL); + hRes = IStream_Write(pStream, &(OlePres.dwExtentX), sizeof(OlePres.dwExtentX), NULL); + hRes = IStream_Write(pStream, &(OlePres.dwExtentY), sizeof(OlePres.dwExtentY), NULL); + hRes = IStream_Write(pStream, &(OlePres.dwSize), sizeof(OlePres.dwSize), NULL); + if(OlePres.dwSize > 0) + { + hRes = IStream_Write(pStream, OlePres.pData, OlePres.dwSize, NULL); + } + IStream_Release(pStream); + } +} + +/************************************************************************* + * OLECONVERT_CreateOle10NativeStream [Internal] + * + * Creates the "\001Ole10Native" Stream (should contain a BMP) + * + * PARAMS + * pStorage [I] Dest storage to create the stream in + * pData [I] Ole10 Native Data (ex. bmp) + * dwDataLength [I] Size of the Ole10 Native Data + * + * RETURNS + * Nothing + * + * NOTES + * This function is used by OleConvertOLESTREAMToIStorage only. + * + * Might need to verify the data and return appropriate error message + * + */ +void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, BYTE *pData, DWORD dwDataLength) +{ + HRESULT hRes; + IStream *pStream; + WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; + + /* Create the Ole10Native Stream */ + hRes = IStorage_CreateStream(pStorage, wstrStreamName, + STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); + + if(hRes == S_OK) + { + /* Write info to stream */ + hRes = IStream_Write(pStream, &dwDataLength, sizeof(dwDataLength), NULL); + hRes = IStream_Write(pStream, pData, dwDataLength, NULL); + IStream_Release(pStream); + } + +} + +/************************************************************************* + * OLECONVERT_GetOLE10ProgID [Internal] + * + * Finds the ProgID (or OleTypeID) from the IStorage + * + * PARAMS + * pStorage [I] The Src IStorage to get the ProgID + * strProgID [I] the ProgID string to get + * dwSize [I] the size of the string + * + * RETURNS + * Success: S_OK + * Failure: REGDB_E_CLASSNOTREG if cannot reconstruct the stream + * + * NOTES + * This function is used by OleConvertIStorageToOLESTREAM only. + * + * + */ +HRESULT OLECONVERT_GetOLE10ProgID(LPSTORAGE pStorage, char *strProgID, DWORD *dwSize) +{ + HRESULT hRes; + IStream *pStream; + LARGE_INTEGER iSeekPos; + OLECONVERT_ISTORAGE_COMPOBJ CompObj; + WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0}; + + /* Open the CompObj Stream */ + hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, + STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); + if(hRes == S_OK) + { + + /*Get the OleType from the CompObj Stream */ + iSeekPos.u.LowPart = sizeof(CompObj.byUnknown1) + sizeof(CompObj.clsid); + iSeekPos.u.HighPart = 0; + + IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL); + IStream_Read(pStream, &CompObj.dwCLSIDNameLength, sizeof(CompObj.dwCLSIDNameLength), NULL); + iSeekPos.u.LowPart = CompObj.dwCLSIDNameLength; + IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR , NULL); + IStream_Read(pStream, &CompObj.dwOleTypeNameLength, sizeof(CompObj.dwOleTypeNameLength), NULL); + iSeekPos.u.LowPart = CompObj.dwOleTypeNameLength; + IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR , NULL); + + IStream_Read(pStream, dwSize, sizeof(*dwSize), NULL); + if(*dwSize > 0) + { + IStream_Read(pStream, strProgID, *dwSize, NULL); + } + IStream_Release(pStream); + } + else + { + STATSTG stat; + LPOLESTR wstrProgID; + + /* Get the OleType from the registry */ + REFCLSID clsid = &(stat.clsid); + IStorage_Stat(pStorage, &stat, STATFLAG_NONAME); + hRes = ProgIDFromCLSID(clsid, &wstrProgID); + if(hRes == S_OK) + { + *dwSize = WideCharToMultiByte(CP_ACP, 0, wstrProgID, -1, strProgID, *dwSize, NULL, FALSE); + } + + } + return hRes; +} + +/************************************************************************* + * OLECONVERT_GetOle10PresData [Internal] + * + * Converts IStorage "/001Ole10Native" stream to a OLE10 Stream + * + * PARAMS + * pStorage [I] Src IStroage + * pOleStream [I] Dest OleStream Mem Struct + * + * RETURNS + * Nothing + * + * NOTES + * This function is used by OleConvertIStorageToOLESTREAM only. + * + * Memory allocated for pData must be freed by the caller + * + * + */ +void OLECONVERT_GetOle10PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) +{ + + HRESULT hRes; + IStream *pStream; + WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; + + /* Initialize Default data for OLESTREAM */ + pOleStreamData[0].dwOleID = OLESTREAM_ID; + pOleStreamData[0].dwTypeID = 2; + pOleStreamData[1].dwOleID = OLESTREAM_ID; + pOleStreamData[1].dwTypeID = 0; + pOleStreamData[0].dwMetaFileWidth = 0; + pOleStreamData[0].dwMetaFileHeight = 0; + pOleStreamData[0].pData = NULL; + pOleStreamData[1].pData = NULL; + + /* Open Ole10Native Stream */ + hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, + STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); + if(hRes == S_OK) + { + + /* Read Size and Data */ + IStream_Read(pStream, &(pOleStreamData->dwDataLength), sizeof(pOleStreamData->dwDataLength), NULL); + if(pOleStreamData->dwDataLength > 0) + { + pOleStreamData->pData = (LPSTR) HeapAlloc(GetProcessHeap(),0,pOleStreamData->dwDataLength); + IStream_Read(pStream, pOleStreamData->pData, pOleStreamData->dwDataLength, NULL); + } + IStream_Release(pStream); + } + +} + + +/************************************************************************* + * OLECONVERT_GetOle20PresData[Internal] + * + * Converts IStorage "/002OlePres000" stream to a OLE10 Stream + * + * PARAMS + * pStorage [I] Src IStroage + * pOleStreamData [I] Dest OleStream Mem Struct + * + * RETURNS + * Nothing + * + * NOTES + * This function is used by OleConvertIStorageToOLESTREAM only. + * + * Memory allocated for pData must be freed by the caller + */ +void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) +{ + HRESULT hRes; + IStream *pStream; + OLECONVERT_ISTORAGE_OLEPRES olePress; + WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0}; + + /* Initialize Default data for OLESTREAM */ + pOleStreamData[0].dwOleID = OLESTREAM_ID; + pOleStreamData[0].dwTypeID = 2; + pOleStreamData[0].dwMetaFileWidth = 0; + pOleStreamData[0].dwMetaFileHeight = 0; + pOleStreamData[0].dwDataLength = OLECONVERT_WriteOLE20ToBuffer(pStorage, &(pOleStreamData[0].pData)); + pOleStreamData[1].dwOleID = OLESTREAM_ID; + pOleStreamData[1].dwTypeID = 0; + pOleStreamData[1].dwOleTypeNameLength = 0; + pOleStreamData[1].strOleTypeName[0] = 0; + pOleStreamData[1].dwMetaFileWidth = 0; + pOleStreamData[1].dwMetaFileHeight = 0; + pOleStreamData[1].pData = NULL; + pOleStreamData[1].dwDataLength = 0; + + + /* Open OlePress000 stream */ + hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, + STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); + if(hRes == S_OK) + { + LARGE_INTEGER iSeekPos; + METAFILEPICT16 MetaFilePict; + char strMetafilePictName[] = "METAFILEPICT"; + + /* Set the TypeID for a Metafile */ + pOleStreamData[1].dwTypeID = 5; + + /* Set the OleTypeName to Metafile */ + pOleStreamData[1].dwOleTypeNameLength = strlen(strMetafilePictName) +1; + strcpy(pOleStreamData[1].strOleTypeName, strMetafilePictName); + + iSeekPos.u.HighPart = 0; + iSeekPos.u.LowPart = sizeof(olePress.byUnknown1); + + /* Get Presentation Data */ + IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL); + IStream_Read(pStream, &(olePress.dwExtentX), sizeof(olePress.dwExtentX), NULL); + IStream_Read(pStream, &(olePress.dwExtentY), sizeof(olePress.dwExtentY), NULL); + IStream_Read(pStream, &(olePress.dwSize), sizeof(olePress.dwSize), NULL); + + /*Set width and Height */ + pOleStreamData[1].dwMetaFileWidth = olePress.dwExtentX; + pOleStreamData[1].dwMetaFileHeight = -olePress.dwExtentY; + if(olePress.dwSize > 0) + { + /* Set Length */ + pOleStreamData[1].dwDataLength = olePress.dwSize + sizeof(METAFILEPICT16); + + /* Set MetaFilePict struct */ + MetaFilePict.mm = 8; + MetaFilePict.xExt = olePress.dwExtentX; + MetaFilePict.yExt = olePress.dwExtentY; + MetaFilePict.hMF = 0; + + /* Get Metafile Data */ + pOleStreamData[1].pData = (BYTE *) HeapAlloc(GetProcessHeap(),0,pOleStreamData[1].dwDataLength); + memcpy(pOleStreamData[1].pData, &MetaFilePict, sizeof(MetaFilePict)); + IStream_Read(pStream, &(pOleStreamData[1].pData[sizeof(MetaFilePict)]), pOleStreamData[1].dwDataLength-sizeof(METAFILEPICT16), NULL); + } + IStream_Release(pStream); + } +} + +/************************************************************************* + * OleConvertOLESTREAMToIStorage [OLE32.87] + * + * Read info on MSDN + * + * TODO + * DVTARGETDEVICE paramenter is not handled + * Still unsure of some mem fields for OLE 10 Stream + * Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj", + * and "\001OLE" streams + * + */ +HRESULT WINAPI OleConvertOLESTREAMToIStorage ( + LPOLESTREAM pOleStream, + LPSTORAGE pstg, + const DVTARGETDEVICE* ptd) +{ + int i; + HRESULT hRes=S_OK; + OLECONVERT_OLESTREAM_DATA pOleStreamData[2]; + + memset(pOleStreamData, 0, sizeof(pOleStreamData)); + + if(ptd != NULL) + { + Print(MIN_TRACE, ("DVTARGETDEVICE is not NULL, unhandled parameter\n")); + } + + if(pstg == NULL || pOleStream == NULL) + { + hRes = E_INVALIDARG; + } + + if(hRes == S_OK) + { + /* Load the OLESTREAM to Memory */ + hRes = OLECONVERT_LoadOLE10(pOleStream, &pOleStreamData[0], TRUE); + } + + if(hRes == S_OK) + { + /* Load the OLESTREAM to Memory (part 2)*/ + hRes = OLECONVERT_LoadOLE10(pOleStream, &pOleStreamData[1], FALSE); + } + + if(hRes == S_OK) + { + + if(pOleStreamData[0].dwDataLength > sizeof(STORAGE_magic)) + { + /* Do we have the IStorage Data in the OLESTREAM */ + if(memcmp(pOleStreamData[0].pData, STORAGE_magic, sizeof(STORAGE_magic)) ==0) + { + OLECONVERT_GetOLE20FromOLE10(pstg, pOleStreamData[0].pData, pOleStreamData[0].dwDataLength); + OLECONVERT_CreateOlePresStream(pstg, pOleStreamData[1].dwMetaFileWidth, pOleStreamData[1].dwMetaFileHeight, pOleStreamData[1].pData, pOleStreamData[1].dwDataLength); + } + else + { + /* It must be an original OLE 1.0 source */ + OLECONVERT_CreateOle10NativeStream(pstg, pOleStreamData[0].pData, pOleStreamData[0].dwDataLength); + } + } + else + { + /* It must be an original OLE 1.0 source */ + OLECONVERT_CreateOle10NativeStream(pstg, pOleStreamData[0].pData, pOleStreamData[0].dwDataLength); + } + + /* Create CompObj Stream if necessary */ + hRes = OLECONVERT_CreateCompObjStream(pstg, pOleStreamData[0].strOleTypeName); + if(hRes == S_OK) + { + /*Create the Ole Stream if necessary */ + OLECONVERT_CreateOleStream(pstg); + } + } + + + /* Free allocated memory */ + for(i=0; i < 2; i++) + { + if(pOleStreamData[i].pData != NULL) + { + HeapFree(GetProcessHeap(),0,pOleStreamData[i].pData); + } + if(pOleStreamData[i].pstrOleObjFileName != NULL) + { + HeapFree(GetProcessHeap(),0,pOleStreamData[i].pstrOleObjFileName); + pOleStreamData[i].pstrOleObjFileName = NULL; + } + } + return hRes; +} + +/************************************************************************* + * OleConvertIStorageToOLESTREAM [OLE32.85] + * + * Read info on MSDN + * + * Read info on MSDN + * + * TODO + * Still unsure of some mem fields for OLE 10 Stream + * Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj", + * and "\001OLE" streams. + * + */ +HRESULT WINAPI OleConvertIStorageToOLESTREAM ( + LPSTORAGE pstg, + LPOLESTREAM pOleStream) +{ + int i; + HRESULT hRes = S_OK; + IStream *pStream; + OLECONVERT_OLESTREAM_DATA pOleStreamData[2]; + WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; + + + memset(pOleStreamData, 0, sizeof(pOleStreamData)); + + if(pstg == NULL || pOleStream == NULL) + { + hRes = E_INVALIDARG; + } + if(hRes == S_OK) + { + /* Get the ProgID */ + pOleStreamData[0].dwOleTypeNameLength = OLESTREAM_MAX_STR_LEN; + hRes = OLECONVERT_GetOLE10ProgID(pstg, pOleStreamData[0].strOleTypeName, &(pOleStreamData[0].dwOleTypeNameLength)); + } + if(hRes == S_OK) + { + /*Was it originaly Ole10 */ + hRes = IStorage_OpenStream(pstg, wstrStreamName, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream); + if(hRes == S_OK) + { + IStream_Release(pStream); + /*Get Presentation Data for Ole10Native */ + OLECONVERT_GetOle10PresData(pstg, pOleStreamData); + } + else + { + /*Get Presentation Data (OLE20)*/ + OLECONVERT_GetOle20PresData(pstg, pOleStreamData); + } + + /* Save OLESTREAM */ + hRes = OLECONVERT_SaveOLE10(&(pOleStreamData[0]), pOleStream); + if(hRes == S_OK) + { + hRes = OLECONVERT_SaveOLE10(&(pOleStreamData[1]), pOleStream); + } + + } + + /* Free allocated memory */ + for(i=0; i < 2; i++) + { + if(pOleStreamData[i].pData != NULL) + { + HeapFree(GetProcessHeap(),0,pOleStreamData[i].pData); + } + } + + return hRes; +} + +/*********************************************************************** + * GetConvertStg (OLE32.68) + */ +HRESULT WINAPI GetConvertStg(LPGUID guid) { + UNIMPLEMENTED; + return E_FAIL; +}