4 * Copyright 1997 Alexandre Julliard
5 * Copyright 1997 Len White
6 * Copyright 1999 Keith Matthews
9 /* Only empty stubs for now */
19 #include "shm_semaph.h"
21 /* Has defined in atom.c file.
23 #define MAX_ATOM_LEN 255
25 /* Maximum buffer size ( including the '\0' ).
27 #define MAX_BUFFER_LEN (MAX_ATOM_LEN + 1)
30 static DDE_HANDLE_ENTRY
*DDE_Handle_Table_Base
= NULL
;
31 static LPDWORD DDE_Max_Assigned_Instance
= 0; // OK for present, may have to worry about wrap-around later
32 static const char inst_string
[]= "DDEMaxInstance";
33 static LPCWSTR DDEInstanceAccess
= (LPCWSTR
)&inst_string
;
34 static const char handle_string
[] = "DDEHandleAccess";
35 static LPCWSTR DDEHandleAccess
= (LPCWSTR
)&handle_string
;
36 static HANDLE32 inst_count_mutex
= 0;
37 static HANDLE32 handle_mutex
= 0;
38 DDE_HANDLE_ENTRY
*this_instance
;
39 SECURITY_ATTRIBUTES
*s_att
= NULL
;
44 LPVOID lpSecurityDescriptor;
45 BOOL32 bInheritHandle;
46 } SECURITY_ATTRIBUTES; */
53 /* This is a simple list to keep track of the strings created
54 * by DdeCreateStringHandle. The list is used to free
55 * the strings whenever DdeUninitialize is called.
56 * This mechanism is not complete and does not handle multiple instances.
57 * Most of the DDE API use a DWORD parameter indicating which instance
58 * of a given program is calling them. The API are supposed to
59 * associate the data to the instance that created it.
61 typedef struct tagHSZNode HSZNode
;
68 /* Start off the list pointer with a NULL.
70 static HSZNode
* pHSZNodes
= NULL
;
73 /******************************************************************************
74 * RemoveHSZNodes (INTERNAL)
76 * Remove a node from the list of HSZ nodes.
78 ******************************************************************************
82 * Vn Date Author Comment
84 * 1.0 Dec 1998 Corel/Macadamian Initial version
87 static void RemoveHSZNode( DWORD idInst
, HSZ hsz
)
89 HSZNode
* pPrev
= NULL
;
90 HSZNode
* pCurrent
= NULL
;
92 /* Set the current node at the start of the list.
95 /* While we have more nodes.
97 while( pCurrent
!= NULL
)
99 /* If we found the node we were looking for.
101 if( pCurrent
->hsz
== hsz
)
105 /* If the first node in the list is to to be removed.
106 * Set the global list pointer to the next node.
108 if( pCurrent
== pHSZNodes
)
110 pHSZNodes
= pCurrent
->next
;
112 /* Just fix the pointers has to skip the current
113 * node so we can delete it.
117 pPrev
->next
= pCurrent
->next
;
119 /* Destroy this node.
124 /* Save the previous node pointer.
127 /* Move on to the next node.
129 pCurrent
= pCurrent
->next
;
133 /******************************************************************************
134 * FreeAndRemoveHSZNodes (INTERNAL)
136 * Frees up all the strings still allocated in the list and
137 * remove all the nodes from the list of HSZ nodes.
139 ******************************************************************************
143 * Vn Date Author Comment
145 * 1.0 Dec 1998 Corel/Macadamian Initial version
148 static void FreeAndRemoveHSZNodes( DWORD idInst
)
150 /* Free any strings created in this instance.
152 while( pHSZNodes
!= NULL
)
154 DdeFreeStringHandle32( idInst
, pHSZNodes
->hsz
);
158 /******************************************************************************
159 * InsertHSZNode (INTERNAL)
161 * Insert a node to the head of the list.
163 ******************************************************************************
167 * Vn Date Author Comment
169 * 1.0 Dec 1998 Corel/Macadamian Initial version
172 static void InsertHSZNode( DWORD idInst
, HSZ hsz
)
176 HSZNode
* pNew
= NULL
;
177 /* Create a new node for this HSZ.
179 pNew
= (HSZNode
*) malloc( sizeof( HSZNode
) );
182 /* Set the handle value.
185 /* Attach the node to the head of the list.
187 pNew
->next
= pHSZNodes
;
188 /* The new node is now at the head of the list
189 * so set the global list pointer to it.
196 /******************************************************************************
197 * Release_reserved_mutex
199 * generic routine to release a reserved mutex
202 ******************************************************************************
206 * Vn Date Author Comment
208 * 1.0 Jan 1999 Keith Matthews Initial version
211 DWORD
Release_reserved_mutex (HANDLE32 mutex
, LPTSTR mutex_name
, BOOL32 release_handle_m
, BOOL32 release_this_i
)
214 if ( (err_no
=GetLastError()) != 0 )
216 ERR(ddeml
,"ReleaseMutex failed - %s mutex %li\n",mutex_name
,err_no
);
217 HeapFree(GetProcessHeap(), 0, this_instance
);
218 if ( release_handle_m
)
220 ReleaseMutex(handle_mutex
);
222 return DMLERR_SYS_ERROR
;
224 if ( release_this_i
)
226 HeapFree(GetProcessHeap(), 0, this_instance
);
228 return DMLERR_NO_ERROR
;
231 /******************************************************************************
232 * IncrementInstanceId
234 * generic routine to increment the max instance Id and allocate a new application instance
236 ******************************************************************************
240 * Vn Date Author Comment
242 * 1.0 Jan 1999 Keith Matthews Initial version
245 DWORD
IncrementInstanceId()
247 SECURITY_ATTRIBUTES s_attrib
;
248 /* Need to set up Mutex in case it is not already present */
249 // increment handle count & get value
250 if ( !inst_count_mutex
)
252 s_attrib
.bInheritHandle
= TRUE
;
253 s_attrib
.lpSecurityDescriptor
= NULL
;
254 s_attrib
.nLength
= sizeof(s_attrib
);
255 inst_count_mutex
= CreateMutex32W(&s_attrib
,1,DDEInstanceAccess
); // 1st time through
257 WaitForSingleObject(inst_count_mutex
,1000); // subsequent calls
258 /* FIXME - needs refinement with popup for timeout, also is timeout interval OK */
260 if ( (err_no
=GetLastError()) == ERROR_INVALID_HANDLE
)
262 ERR(ddeml
,"CreateMutex failed - inst_count %li\n",err_no
);
263 err_no
=Release_reserved_mutex (handle_mutex
,"handle_mutex",0,1);
264 return DMLERR_SYS_ERROR
;
266 DDE_Max_Assigned_Instance
++;
267 this_instance
->Instance_id
= DDE_Max_Assigned_Instance
;
268 if (Release_reserved_mutex(inst_count_mutex
,"instance_count",1,0)) return DMLERR_SYS_ERROR
;
269 return DMLERR_NO_ERROR
;
272 /******************************************************************************
273 * DdeInitialize16 (DDEML.2)
275 UINT16 WINAPI
DdeInitialize16( LPDWORD pidInst
, PFNCALLBACK16 pfnCallback
,
276 DWORD afCmd
, DWORD ulRes
)
278 return (UINT16
)DdeInitialize32A(pidInst
,(PFNCALLBACK32
)pfnCallback
,
283 /******************************************************************************
284 * DdeInitialize32A (USER32.106)
286 UINT32 WINAPI
DdeInitialize32A( LPDWORD pidInst
, PFNCALLBACK32 pfnCallback
,
287 DWORD afCmd
, DWORD ulRes
)
289 return DdeInitialize32W(pidInst
,pfnCallback
,afCmd
,ulRes
);
293 /******************************************************************************
294 * DdeInitialize32W [USER32.107]
295 * Registers an application with the DDEML
298 * pidInst [I] Pointer to instance identifier
299 * pfnCallback [I] Pointer to callback function
300 * afCmd [I] Set of command and filter flags
304 * Success: DMLERR_NO_ERROR
305 * Failure: DMLERR_DLL_USAGE, DMLERR_INVALIDPARAMETER, DMLERR_SYS_ERROR
307 ******************************************************************************
311 * Vn Date Author Comment
313 * 1.0 Pre 1998 Alexandre/Len Initial Stub
314 * 1.1 Jan 1999 Keith Matthews Initial (near-)complete version
317 UINT32 WINAPI
DdeInitialize32W( LPDWORD pidInst
, PFNCALLBACK32 pfnCallback
,
318 DWORD afCmd
, DWORD ulRes
)
320 DDE_HANDLE_ENTRY
*reference_inst
;
321 SECURITY_ATTRIBUTES s_attrib
;
324 // probably not really capable of handling mutliple processes, but should handle
325 // multiple instances within one process
329 ERR(dde
, "Reserved value not zero? What does this mean?\n");
330 FIXME(ddeml
, "(%p,%p,0x%lx,%ld): stub\n",pidInst
,pfnCallback
,afCmd
,ulRes
);
331 /* trap this and no more until we know more */
332 return DMLERR_NO_ERROR
;
336 /* can't set up the instance with nothing to act as a callback */
337 TRACE(ddeml
,"No callback provided\n");
338 return DMLERR_INVALIDPARAMETER
; /* might be DMLERR_DLL_USAGE */
341 /* grab enough heap for one control struct - not really necessary for re-initialise
342 but allows us to use same validation routines */
343 this_instance
= (DDE_HANDLE_ENTRY
*)HeapAlloc( SystemHeap
, 0, sizeof(DDE_HANDLE_ENTRY
) );
344 if ( this_instance
== NULL
)
346 // catastrophe !! warn user & abort
347 ERR (ddeml
,"Instance create failed - out of memory\n");
348 return DMLERR_SYS_ERROR
;
350 this_instance
->Next_Entry
= NULL
;
351 this_instance
->Monitor
=(afCmd
|APPCLASS_MONITOR
);
353 // messy bit, spec implies that 'Client Only' can be set in 2 different ways, catch 1 here
355 this_instance
->Client_only
=afCmd
&APPCMD_CLIENTONLY
;
356 this_instance
->Instance_id
= pidInst
; // May need to add calling proc Id
357 this_instance
->CallBack
=*pfnCallback
;
358 this_instance
->Txn_count
=0;
359 this_instance
->Unicode
= TRUE
;
360 this_instance
->Win16
= FALSE
;
361 this_instance
->Monitor_flags
= afCmd
& MF_MASK
;
363 // isolate CBF flags in one go, expect this will go the way of all attempts to be clever !!
365 this_instance
->CBF_Flags
=afCmd
^((afCmd
&MF_MASK
)|((afCmd
&APPCMD_MASK
)|(afCmd
&APPCLASS_MASK
)));
367 if ( ! this_instance
->Client_only
)
370 // Check for other way of setting Client-only !!
372 this_instance
->Client_only
=(this_instance
->CBF_Flags
&CBF_FAIL_ALLSVRXACTIONS
)
373 ==CBF_FAIL_ALLSVRXACTIONS
;
376 TRACE(ddeml
,"instance created - checking validity \n");
378 if( *pidInst
== 0 ) {
379 /* Initialisation of new Instance Identifier */
380 TRACE(ddeml
,"new instance, callback %p flags %lX\n",pfnCallback
,afCmd
);
381 /* Need to set up Mutex in case it is not already present */
382 s_att
->bInheritHandle
= TRUE
;
383 s_att
->lpSecurityDescriptor
= NULL
;
384 s_att
->nLength
= sizeof(s_att
);
385 handle_mutex
= CreateMutex32W(s_att
,1,DDEHandleAccess
);
386 if ( (err_no
=GetLastError()) == ERROR_INVALID_HANDLE
)
388 ERR(ddeml
,"CreateMutex failed - handle list %li\n",err_no
);
389 HeapFree(GetProcessHeap(), 0, this_instance
);
390 return DMLERR_SYS_ERROR
;
392 TRACE(ddeml
,"Handle Mutex created/reserved\n");
393 if (DDE_Handle_Table_Base
== NULL
)
395 /* can't be another instance in this case, assign to the base pointer */
396 DDE_Handle_Table_Base
= this_instance
;
398 // since first must force filter of XTYP_CONNECT and XTYP_WILDCONNECT for
400 // ------------------------------- NOTE NOTE NOTE --------------------------
402 // the manual is not clear if this condition
403 // applies to the first call to DdeInitialize from an application, or the
404 // first call for a given callback !!!
407 this_instance
->CBF_Flags
=this_instance
->CBF_Flags
|APPCMD_FILTERINITS
;
408 TRACE(ddeml
,"First application instance detected OK\n");
409 // allocate new instance ID
410 if ((err_no
= IncrementInstanceId()) ) return err_no
;
412 /* really need to chain the new one in to the latest here, but after checking conditions
413 such as trying to start a conversation from an application trying to monitor */
414 reference_inst
= DDE_Handle_Table_Base
;
415 TRACE(ddeml
,"Subsequent application instance - starting checks\n");
416 while ( reference_inst
->Next_Entry
!= NULL
)
419 // This set of tests will work if application uses same instance Id
420 // at application level once allocated - which is what manual implies
421 // should happen. If someone tries to be
422 // clever (lazy ?) it will fail to pick up that later calls are for
423 // the same application - should we trust them ?
425 if ( this_instance
->Instance_id
== reference_inst
->Instance_id
)
427 // Check 1 - must be same Client-only state
429 if ( this_instance
->Client_only
!= reference_inst
->Client_only
)
431 if ( Release_reserved_mutex(handle_mutex
,"handle_mutex",0,1))
432 return DMLERR_SYS_ERROR
;
433 return DMLERR_DLL_USAGE
;
436 // Check 2 - cannot use 'Monitor' with any non-monitor modes
438 if ( this_instance
->Monitor
!= reference_inst
->Monitor
)
440 if ( Release_reserved_mutex(handle_mutex
,"handle_mutex",0,1))
441 return DMLERR_SYS_ERROR
;
442 return DMLERR_INVALIDPARAMETER
;
445 // Check 3 - must supply different callback address
447 if ( this_instance
->CallBack
== reference_inst
->CallBack
)
449 if ( Release_reserved_mutex(handle_mutex
,"handle_mutex",0,1))
450 return DMLERR_SYS_ERROR
;
451 return DMLERR_DLL_USAGE
;
454 reference_inst
= reference_inst
->Next_Entry
;
456 // All cleared, add to chain
458 TRACE(ddeml
,"Application Instance checks finished\n");
459 if ((err_no
= IncrementInstanceId())) return err_no
;
460 if ( Release_reserved_mutex(handle_mutex
,"handle_mutex",0,0)) return DMLERR_SYS_ERROR
;
461 reference_inst
->Next_Entry
= this_instance
;
463 pidInst
= (LPDWORD
)this_instance
->Instance_id
;
464 TRACE(ddeml
,"New application instance processing finished OK\n");
466 /* Reinitialisation situation --- FIX */
467 TRACE(ddeml
,"reinitialisation of (%p,%p,0x%lx,%ld): stub\n",pidInst
,pfnCallback
,afCmd
,ulRes
);
468 WaitForSingleObject(handle_mutex
,1000);
469 if ( (err_no
=GetLastError()) != 0 )
472 /* FIXME - needs refinement with popup for timeout, also is timeout interval OK */
474 ERR(ddeml
,"WaitForSingleObject failed - handle list %li\n",err_no
);
475 HeapFree(GetProcessHeap(), 0, this_instance
);
476 return DMLERR_SYS_ERROR
;
478 if (DDE_Handle_Table_Base
== NULL
)
480 if ( Release_reserved_mutex(handle_mutex
,"handle_mutex",0,1)) return DMLERR_SYS_ERROR
;
481 return DMLERR_DLL_USAGE
;
483 HeapFree(GetProcessHeap(), 0, this_instance
); // finished - release heap space used as work store
484 // can't reinitialise if we have initialised nothing !!
485 reference_inst
= DDE_Handle_Table_Base
;
486 /* must first check if we have been given a valid instance to re-initialise !! how do we do that ? */
487 while ( reference_inst
->Next_Entry
!= NULL
)
489 if ( pidInst
== reference_inst
->Instance_id
&& pfnCallback
== reference_inst
->CallBack
)
491 // Check 1 - cannot change client-only mode if set via APPCMD_CLIENTONLY
493 if ( reference_inst
->Client_only
)
495 if ((reference_inst
->CBF_Flags
& CBF_FAIL_ALLSVRXACTIONS
) != CBF_FAIL_ALLSVRXACTIONS
)
497 // i.e. Was set to Client-only and through APPCMD_CLIENTONLY
499 if ( ! ( afCmd
& APPCMD_CLIENTONLY
))
501 if ( Release_reserved_mutex(handle_mutex
,"handle_mutex",0,1))
502 return DMLERR_SYS_ERROR
;
503 return DMLERR_DLL_USAGE
;
507 // Check 2 - cannot change monitor modes
509 if ( this_instance
->Monitor
!= reference_inst
->Monitor
)
511 if ( Release_reserved_mutex(handle_mutex
,"handle_mutex",0,1))
512 return DMLERR_SYS_ERROR
;
513 return DMLERR_DLL_USAGE
;
516 // Check 3 - trying to set Client-only via APPCMD when not set so previously
518 if (( afCmd
&APPCMD_CLIENTONLY
) && ! reference_inst
->Client_only
)
520 if ( Release_reserved_mutex(handle_mutex
,"handle_mutex",0,1))
521 return DMLERR_SYS_ERROR
;
522 return DMLERR_DLL_USAGE
;
526 // All checked - change relevant flags
528 reference_inst
->CBF_Flags
= this_instance
->CBF_Flags
;
529 reference_inst
->Client_only
= this_instance
->Client_only
;
530 reference_inst
->Monitor_flags
= this_instance
->Monitor_flags
;
531 if ( Release_reserved_mutex(handle_mutex
,"handle_mutex",0,1))
532 return DMLERR_SYS_ERROR
;
535 return DMLERR_NO_ERROR
;
539 /*****************************************************************
540 * DdeUninitialize16 (DDEML.3)
542 BOOL16 WINAPI
DdeUninitialize16( DWORD idInst
)
544 return (BOOL16
)DdeUninitialize32( idInst
);
548 /*****************************************************************
549 * DdeUninitialize32 [USER32.119] Frees DDEML resources
552 * idInst [I] Instance identifier
558 BOOL32 WINAPI
DdeUninitialize32( DWORD idInst
)
561 FIXME(ddeml
, "(%ld): stub\n", idInst
);
563 /* Free the nodes that were not freed by this instance
564 * and remove the nodes from the list of HSZ nodes.
566 FreeAndRemoveHSZNodes( idInst
);
572 /*****************************************************************
573 * DdeConnectList16 [DDEML.4]
575 HCONVLIST WINAPI
DdeConnectList16( DWORD idInst
, HSZ hszService
, HSZ hszTopic
,
576 HCONVLIST hConvList
, LPCONVCONTEXT16 pCC
)
578 return DdeConnectList32(idInst
, hszService
, hszTopic
, hConvList
,
579 (LPCONVCONTEXT32
)pCC
);
583 /******************************************************************************
584 * DdeConnectList32 [USER32.93] Establishes conversation with DDE servers
587 * idInst [I] Instance identifier
588 * hszService [I] Handle to service name string
589 * hszTopic [I] Handle to topic name string
590 * hConvList [I] Handle to conversation list
591 * pCC [I] Pointer to structure with context data
594 * Success: Handle to new conversation list
597 HCONVLIST WINAPI
DdeConnectList32( DWORD idInst
, HSZ hszService
, HSZ hszTopic
,
598 HCONVLIST hConvList
, LPCONVCONTEXT32 pCC
)
600 FIXME(ddeml
, "(%ld,%ld,%ld,%ld,%p): stub\n", idInst
, hszService
, hszTopic
,
606 /*****************************************************************
607 * DdeQueryNextServer16 [DDEML.5]
609 HCONV WINAPI
DdeQueryNextServer16( HCONVLIST hConvList
, HCONV hConvPrev
)
611 return DdeQueryNextServer32(hConvList
, hConvPrev
);
615 /*****************************************************************
616 * DdeQueryNextServer32 [USER32.112]
618 HCONV WINAPI
DdeQueryNextServer32( HCONVLIST hConvList
, HCONV hConvPrev
)
620 FIXME(ddeml
, "(%ld,%ld): stub\n",hConvList
,hConvPrev
);
624 /*****************************************************************
625 * DdeQueryString32A [USER32.113]
627 DWORD WINAPI
DdeQueryString32A(DWORD idInst
, HSZ hsz
, LPSTR psz
, DWORD cchMax
, INT32 iCodePage
)
630 CHAR pString
[MAX_BUFFER_LEN
];
633 "(%ld, 0x%lx, %p, %ld, %d): stub\n",
640 if( iCodePage
== CP_WINANSI
)
642 /* If psz is null, we have to return only the length
648 cchMax
= MAX_BUFFER_LEN
;
651 ret
= GlobalGetAtomName32A( hsz
, (LPSTR
)psz
, cchMax
);
657 /*****************************************************************
658 * DdeQueryString32W [USER32.114]
660 DWORD WINAPI
DdeQueryString32W(DWORD idInst
, HSZ hsz
, LPWSTR psz
, DWORD cchMax
, INT32 iCodePage
)
663 WCHAR pString
[MAX_BUFFER_LEN
];
667 "(%ld, 0x%lx, %p, %ld, %d): stub\n",
674 if( iCodePage
== CP_WINUNICODE
)
676 /* If psz is null, we have to return only the length
682 cchMax
= MAX_BUFFER_LEN
;
683 /* Note: According to documentation if the psz parameter
684 * was NULL this API must return the length of the string in bytes.
686 factor
= (int) sizeof(WCHAR
)/sizeof(BYTE
);
688 ret
= GlobalGetAtomName32W( hsz
, (LPWSTR
)psz
, cchMax
) * factor
;
694 /*****************************************************************
695 * DdeDisconnectList (DDEML.6)
697 BOOL16 WINAPI
DdeDisconnectList16( HCONVLIST hConvList
)
699 return (BOOL16
)DdeDisconnectList32(hConvList
);
703 /******************************************************************************
704 * DdeDisconnectList32 [USER32.98] Destroys list and terminates conversations
710 BOOL32 WINAPI
DdeDisconnectList32(
711 HCONVLIST hConvList
) /* [in] Handle to conversation list */
713 FIXME(ddeml
, "(%ld): stub\n", hConvList
);
718 /*****************************************************************
719 * DdeConnect16 (DDEML.7)
721 HCONV WINAPI
DdeConnect16( DWORD idInst
, HSZ hszService
, HSZ hszTopic
,
722 LPCONVCONTEXT16 pCC
)
724 FIXME( ddeml
, "empty stub\n" );
729 /*****************************************************************
730 * DdeConnect32 (USER32.92)
732 HCONV WINAPI
DdeConnect32( DWORD idInst
, HSZ hszService
, HSZ hszTopic
,
733 LPCONVCONTEXT32 pCC
)
735 FIXME(ddeml
, "(0x%lx,%ld,%ld,%p): stub\n",idInst
,hszService
,hszTopic
,
741 /*****************************************************************
742 * DdeDisconnect16 (DDEML.8)
744 BOOL16 WINAPI
DdeDisconnect16( HCONV hConv
)
746 return (BOOL16
)DdeDisconnect32( hConv
);
749 /*****************************************************************
750 * DdeSetUserHandle (DDEML.10)
752 BOOL16 WINAPI
DdeSetUserHandle( HCONV hConv
, DWORD id
, DWORD hUser
)
754 FIXME( ddeml
, "(%ld,%ld,%ld): stub\n",hConv
,id
, hUser
);
758 /*****************************************************************
759 * DdeCreateDataHandle16 (DDEML.14)
761 HDDEDATA WINAPI
DdeCreateDataHandle16( DWORD idInst
, LPBYTE pSrc
, DWORD cb
,
762 DWORD cbOff
, HSZ hszItem
, UINT16 wFmt
,
765 return DdeCreateDataHandle32(idInst
,
774 /*****************************************************************
775 * DdeCreateDataHandle32 (USER32.94)
777 HDDEDATA WINAPI
DdeCreateDataHandle32( DWORD idInst
, LPBYTE pSrc
, DWORD cb
,
778 DWORD cbOff
, HSZ hszItem
, UINT32 wFmt
,
782 "(%ld,%p,%ld,%ld,0x%lx,%d,%d): stub\n",
794 /*****************************************************************
795 * DdeDisconnect32 (USER32.97)
797 BOOL32 WINAPI
DdeDisconnect32( HCONV hConv
)
799 FIXME( ddeml
, "empty stub\n" );
804 /*****************************************************************
805 * DdeReconnect (DDEML.37) (USER32.115)
807 HCONV WINAPI
DdeReconnect( HCONV hConv
)
809 FIXME( ddeml
, "empty stub\n" );
814 /*****************************************************************
815 * DdeCreateStringHandle16 (DDEML.21)
817 HSZ WINAPI
DdeCreateStringHandle16( DWORD idInst
, LPCSTR str
, INT16 codepage
)
819 return DdeCreateStringHandle32A( idInst
, str
, codepage
);
823 /*****************************************************************
824 * DdeCreateStringHandle32A [USER32.95]
827 * Success: String handle
830 HSZ WINAPI
DdeCreateStringHandle32A( DWORD idInst
, LPCSTR psz
, INT32 codepage
)
833 TRACE(ddeml
, "(%ld,%s,%d): stub\n",idInst
,debugstr_a(psz
),codepage
);
835 if (codepage
==CP_WINANSI
)
837 hsz
= GlobalAddAtom32A (psz
);
838 /* Save the handle so we know to clean it when
839 * uninitialize is called.
841 InsertHSZNode( idInst
, hsz
);
848 /******************************************************************************
849 * DdeCreateStringHandle32W [USER32.96] Creates handle to identify string
852 * Success: String handle
855 HSZ WINAPI
DdeCreateStringHandle32W(
856 DWORD idInst
, /* [in] Instance identifier */
857 LPCWSTR psz
, /* [in] Pointer to string */
858 INT32 codepage
) /* [in] Code page identifier */
862 FIXME(ddeml
, "(%ld,%s,%d): stub\n",idInst
,debugstr_w(psz
),codepage
);
864 if (codepage
==CP_WINUNICODE
)
866 hsz
= GlobalAddAtom32W (psz
);
867 /* Save the handle so we know to clean it when
868 * uninitialize is called.
870 InsertHSZNode( idInst
, hsz
);
877 /*****************************************************************
878 * DdeFreeStringHandle16 (DDEML.22)
880 BOOL16 WINAPI
DdeFreeStringHandle16( DWORD idInst
, HSZ hsz
)
882 return (BOOL32
)DdeFreeStringHandle32( idInst
, hsz
);
886 /*****************************************************************
887 * DdeFreeStringHandle32 (USER32.101)
888 * RETURNS: success: nonzero
891 BOOL32 WINAPI
DdeFreeStringHandle32( DWORD idInst
, HSZ hsz
)
893 TRACE( ddeml
, "(%ld,%ld): stub\n",idInst
, hsz
);
894 /* Remove the node associated with this HSZ.
896 RemoveHSZNode( idInst
, hsz
);
897 /* Free the string associated with this HSZ.
899 return GlobalDeleteAtom (hsz
) ? 0 : hsz
;
903 /*****************************************************************
904 * DdeFreeDataHandle16 (DDEML.19)
906 BOOL16 WINAPI
DdeFreeDataHandle16( HDDEDATA hData
)
908 return (BOOL32
)DdeFreeDataHandle32( hData
);
912 /*****************************************************************
913 * DdeFreeDataHandle32 (USER32.100)
915 BOOL32 WINAPI
DdeFreeDataHandle32( HDDEDATA hData
)
917 FIXME( ddeml
, "empty stub\n" );
924 /*****************************************************************
925 * DdeKeepStringHandle16 (DDEML.24)
927 BOOL16 WINAPI
DdeKeepStringHandle16( DWORD idInst
, HSZ hsz
)
929 return (BOOL32
)DdeKeepStringHandle32( idInst
, hsz
);
933 /*****************************************************************
934 * DdeKeepStringHandle32 (USER32.108)
936 BOOL32 WINAPI
DdeKeepStringHandle32( DWORD idInst
, HSZ hsz
)
938 FIXME( ddeml
, "empty stub\n" );
943 /*****************************************************************
944 * DdeClientTransaction16 (DDEML.11)
946 HDDEDATA WINAPI
DdeClientTransaction16( LPVOID pData
, DWORD cbData
,
947 HCONV hConv
, HSZ hszItem
, UINT16 wFmt
,
948 UINT16 wType
, DWORD dwTimeout
,
951 return DdeClientTransaction32( (LPBYTE
)pData
, cbData
, hConv
, hszItem
,
952 wFmt
, wType
, dwTimeout
, pdwResult
);
956 /*****************************************************************
957 * DdeClientTransaction32 (USER32.90)
959 HDDEDATA WINAPI
DdeClientTransaction32( LPBYTE pData
, DWORD cbData
,
960 HCONV hConv
, HSZ hszItem
, UINT32 wFmt
,
961 UINT32 wType
, DWORD dwTimeout
,
964 FIXME( ddeml
, "empty stub\n" );
968 /*****************************************************************
969 * DdeAbandonTransaction (DDEML.12)
971 BOOL16 WINAPI
DdeAbandonTransaction( DWORD idInst
, HCONV hConv
,
972 DWORD idTransaction
)
974 FIXME( ddeml
, "empty stub\n" );
979 /*****************************************************************
980 * DdePostAdvise16 [DDEML.13]
982 BOOL16 WINAPI
DdePostAdvise16( DWORD idInst
, HSZ hszTopic
, HSZ hszItem
)
984 return (BOOL16
)DdePostAdvise32(idInst
, hszTopic
, hszItem
);
988 /******************************************************************************
989 * DdePostAdvise32 [USER32.110] Send transaction to DDE callback function.
995 BOOL32 WINAPI
DdePostAdvise32(
996 DWORD idInst
, /* [in] Instance identifier */
997 HSZ hszTopic
, /* [in] Handle to topic name string */
998 HSZ hszItem
) /* [in] Handle to item name string */
1000 FIXME(ddeml
, "(%ld,%ld,%ld): stub\n",idInst
,hszTopic
,hszItem
);
1005 /*****************************************************************
1006 * DdeAddData (DDEML.15)
1008 HDDEDATA WINAPI
DdeAddData( HDDEDATA hData
, LPBYTE pSrc
, DWORD cb
,
1011 FIXME( ddeml
, "empty stub\n" );
1016 /******************************************************************************
1017 * DdeGetData32 [USER32.102] Copies data from DDE object ot local buffer
1020 * Size of memory object associated with handle
1022 DWORD WINAPI
DdeGetData32(
1023 HDDEDATA hData
, /* [in] Handle to DDE object */
1024 LPBYTE pDst
, /* [in] Pointer to destination buffer */
1025 DWORD cbMax
, /* [in] Amount of data to copy */
1026 DWORD cbOff
) /* [in] Offset to beginning of data */
1028 FIXME(ddeml
, "(%ld,%p,%ld,%ld): stub\n",hData
,pDst
,cbMax
,cbOff
);
1033 /*****************************************************************
1034 * DdeGetData16 [DDEML.16]
1036 DWORD WINAPI
DdeGetData16(
1042 return DdeGetData32(hData
, pDst
, cbMax
, cbOff
);
1046 /*****************************************************************
1047 * DdeAccessData16 (DDEML.17)
1049 LPBYTE WINAPI
DdeAccessData16( HDDEDATA hData
, LPDWORD pcbDataSize
)
1051 return DdeAccessData32(hData
, pcbDataSize
);
1054 /*****************************************************************
1055 * DdeAccessData32 (USER32.88)
1057 LPBYTE WINAPI
DdeAccessData32( HDDEDATA hData
, LPDWORD pcbDataSize
)
1059 FIXME( ddeml
, "(%ld,%p): stub\n", hData
, pcbDataSize
);
1063 /*****************************************************************
1064 * DdeUnaccessData16 (DDEML.18)
1066 BOOL16 WINAPI
DdeUnaccessData16( HDDEDATA hData
)
1068 return DdeUnaccessData32(hData
);
1071 /*****************************************************************
1072 * DdeUnaccessData32 (USER32.118)
1074 BOOL32 WINAPI
DdeUnaccessData32( HDDEDATA hData
)
1076 FIXME( ddeml
, "(0x%lx): stub\n", hData
);
1081 /*****************************************************************
1082 * DdeEnableCallback16 (DDEML.26)
1084 BOOL16 WINAPI
DdeEnableCallback16( DWORD idInst
, HCONV hConv
, UINT16 wCmd
)
1086 return DdeEnableCallback32(idInst
, hConv
, wCmd
);
1089 /*****************************************************************
1090 * DdeEnableCallback32 (USER32.99)
1092 BOOL32 WINAPI
DdeEnableCallback32( DWORD idInst
, HCONV hConv
, UINT32 wCmd
)
1094 FIXME( ddeml
, "(%ld, 0x%lx, %d) stub\n", idInst
, hConv
, wCmd
);
1099 /*****************************************************************
1100 * DdeNameService16 (DDEML.27)
1102 HDDEDATA WINAPI
DdeNameService16( DWORD idInst
, HSZ hsz1
, HSZ hsz2
,
1105 return DdeNameService32( idInst
, hsz1
, hsz2
, afCmd
);
1109 /******************************************************************************
1110 * DdeNameService32 [USER32.109] {Un}registers service name of DDE server
1113 * idInst [I] Instance identifier
1114 * hsz1 [I] Handle to service name string
1116 * afCmd [I] Service name flags
1122 HDDEDATA WINAPI
DdeNameService32( DWORD idInst
, HSZ hsz1
, HSZ hsz2
,
1125 FIXME(ddeml
, "(%ld,%ld,%ld,%d): stub\n",idInst
,hsz1
,hsz2
,afCmd
);
1130 /*****************************************************************
1131 * DdeGetLastError16 (DDEML.20)
1133 UINT16 WINAPI
DdeGetLastError16( DWORD idInst
)
1135 return (UINT16
)DdeGetLastError32( idInst
);
1139 /******************************************************************************
1140 * DdeGetLastError32 [USER32.103] Gets most recent error code
1143 * idInst [I] Instance identifier
1148 UINT32 WINAPI
DdeGetLastError32( DWORD idInst
)
1150 FIXME(ddeml
, "(%ld): stub\n",idInst
);
1155 /*****************************************************************
1156 * DdeCmpStringHandles16 (DDEML.36)
1158 int WINAPI
DdeCmpStringHandles16( HSZ hsz1
, HSZ hsz2
)
1160 return DdeCmpStringHandles32(hsz1
, hsz2
);
1163 /*****************************************************************
1164 * DdeCmpStringHandles32 (USER32.91)
1166 * Compares the value of two string handles. This comparison is
1167 * not case sensitive.
1170 * -1 The value of hsz1 is zero or less than hsz2
1171 * 0 The values of hsz 1 and 2 are the same or both zero.
1172 * 1 The value of hsz2 is zero of less than hsz1
1174 int WINAPI
DdeCmpStringHandles32( HSZ hsz1
, HSZ hsz2
)
1176 CHAR psz1
[MAX_BUFFER_LEN
];
1177 CHAR psz2
[MAX_BUFFER_LEN
];
1181 TRACE( ddeml
, "handle 1, handle 2\n" );
1183 ret1
= GlobalGetAtomName32A( hsz1
, psz1
, MAX_BUFFER_LEN
);
1184 ret2
= GlobalGetAtomName32A( hsz2
, psz2
, MAX_BUFFER_LEN
);
1185 /* Make sure we found both strings.
1187 if( ret1
== 0 && ret2
== 0 )
1189 /* If both are not found, return both "zero strings".
1193 else if( ret1
== 0 )
1195 /* If hsz1 is a not found, return hsz1 is "zero string".
1199 else if( ret2
== 0 )
1201 /* If hsz2 is a not found, return hsz2 is "zero string".
1207 /* Compare the two strings we got ( case insensitive ).
1209 ret
= strcasecmp( psz1
, psz2
);
1210 /* Since strcmp returns any number smaller than
1211 * 0 when the first string is found to be less than
1212 * the second one we must make sure we are returning
1213 * the proper values.
1228 /*****************************************************************
1229 * PackDDElParam (USER32.414)
1235 UINT32 WINAPI
PackDDElParam(UINT32 msg
, UINT32 uiLo
, UINT32 uiHi
)
1237 FIXME(ddeml
, "stub.\n");
1242 /*****************************************************************
1243 * UnpackDDElParam (USER32.562)
1249 UINT32 WINAPI
UnpackDDElParam(UINT32 msg
, UINT32 lParam
,
1250 UINT32
*uiLo
, UINT32
*uiHi
)
1252 FIXME(ddeml
, "stub.\n");
1257 /*****************************************************************
1258 * FreeDDElParam (USER32.204)
1264 UINT32 WINAPI
FreeDDElParam(UINT32 msg
, UINT32 lParam
)
1266 FIXME(ddeml
, "stub.\n");
1270 /*****************************************************************
1271 * ReuseDDElParam (USER32.446)
1274 UINT32 WINAPI
ReuseDDElParam(UINT32 lParam
, UINT32 msgIn
, UINT32 msgOut
,
1275 UINT32 uiLi
, UINT32 uiHi
)
1277 FIXME(ddeml
, "stub.\n");