summaryrefslogblamecommitdiffstats
path: root/private/ole32/com/dde/server/srvr.h
blob: f2e410f3317192404a05e1bb0c183e0cf8366d1f (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656















































































































































































































































































































































































































































































































































































































































































                                                                                                                         
/****************************** Module Header ******************************\
* Module Name: srvr.h
*
* PURPOSE: Private definitions file for server code
*
* Created: 1990
*
* Copyright (c) 1990, 1991  Microsoft Corporation
*
* History:
*  Raor (../../90,91)  Original
*
\***************************************************************************/
//
// One of the oleint.h routines redefines GlobalAlloc and friends
// to perform some memory tracking functions.
//
// This doesn't work in these files, since the tracking functions
// add tail checking, and size to the data structures. GlobalSize
// is a common function to use to determine how much data to
// serialize, plus it turns out that the other side of a DDE
// connection will often be the caller to free the memory.
//
// Therefore, OLE_DDE_NO_GLOBAL_TRACKING is used to disable this in the
// global header file ih\memapi.hxx. Check to insure this
// flag is set on the compile line
//
#if !defined(OLE_DDE_NO_GLOBAL_TRACKING)
error OLE_DDE_OLE_DDE_NO_GLOBAL_TRACKING must be defined to build this directory
#endif

#include <dde.h>
#include <ddeerr.h>
#include "ddeatoms.h"
#include "ddepack.h"
#include <callctrl.hxx>
#include <ddeint.h>
#include <ddechc.hxx>
#include <longname.h>

//#define UPDATE
/*
 if UPDATE is defined it means:
 If a 1.0 client advises on save, also do a data advise.
 This way the client will always
 have an up-to-date picture (and native data) with respect to a
 2.0 server, like 2.0 clients do.
 If a 1.0 client is prepared to accept data at save time
 it should be able to handle data on each change: it is	exactly
 as if the user chose File.Update after each change.
 In fact the item atom is appended with /Save, (see SendDataMsg1)
 which is sort of a lie, but is what a 1.0 client expects for an
 embedded object.
 This is a UI issue.
*/

#define DEFSTD_ITEM_INDEX   0
#define STDTARGETDEVICE     1
#define STDDOCDIMENSIONS    2
#define STDCOLORSCHEME      3
#define STDHOSTNAMES        4


#define PROTOCOL_EDIT       (OLESTR("StdFileEditing"))
#define PROTOCOL_EXECUTE    (OLESTR("StdExecute"))

#define   ISATOM(a)     ((a >= 0xC000) && (a <= 0xFFFF))

// same limit as in OLE 1.0
#define   MAX_STR       124

#define   WW_LPTR       0       // ptr tosrvr/doc/item
#define   WW_HANDLE     4       // instance handle
#define   WW_LE         8       // signature


#define   WC_LE         0x4c45  // LE chars


// Signatures for validity checking
typedef enum
{
	chkDdeSrvr   = 0x1234,
 	chkDefClient = 0x5678
} CHK;


const DWORD grfCreateStg =	STGM_READWRITE | STGM_SHARE_EXCLUSIVE
									| STGM_DIRECT | STGM_CREATE ;


// If we running under WLO, the HIGHWORD of version number will be >= 0x0A00
#define VER_WLO     0x0A00

extern  "C" WORD CheckPointer (LPVOID, int);

#define READ_ACCESS     0
#define WRITE_ACCESS    1

#define PROBE_READ(lp){\
        if (!CheckPointer(lp, READ_ACCESS))\
            return ReportResult(0, E_INVALIDARG, 0, 0);  \
}

#define PROBE_WRITE(lp){\
        if (!CheckPointer(lp, WRITE_ACCESS))\
            return ReportResult(0, E_INVALIDARG, 0, 0);  \
}

#define   OLE_COMMAND       1
#define   NON_OLE_COMMAND   2


#define   WT_SRVR           0       // server window
#define   WT_DOC            1       // document window

#define   PROBE_BLOCK(lpsrvr) {             \
    if (lpsrvr->bBlock)                     \
        return ReportResult(0, S_SERVER_BLOCKED, 0, 0);    \
}


#define   SET_MSG_STATUS(retval, status) { \
    if (!FAILED (GetScode (retval)))     \
        status |= 0x8000;                  \
    if (GetScode(retval) == RPC_E_SERVERCALL_RETRYLATER)\
        status |= 0x4000;                  \
}


/* Codes for CallBack events */
typedef enum {
    OLE_CHANGED,            /* 0                                             */
    OLE_SAVED,              /* 1                                             */
    OLE_CLOSED,             /* 2                                             */
    OLE_RENAMED,            /* 3                                             */
} OLE_NOTIFICATION;

typedef enum { cnvtypNone, cnvtypConvertTo, cnvtypTreatAs } CNVTYP;

typedef struct _QUE : public CPrivAlloc {   // nodes in Block/Unblock queue
    HWND        hwnd;       //***
    UINT		msg;        //      window
    WPARAM      wParam;     //      procedure parameters
    LPARAM      lParam;     //***
    HANDLE      hqNext;     // handle to next node
} QUE;

typedef QUE NEAR *  PQUE;
typedef QUE FAR *   LPQUE;

// structure for maintaining the client info.
#define         LIST_SIZE       10
typedef  struct _CLILIST : public CPrivAlloc {
    HANDLE                 hcliNext;
    HANDLE                 info[LIST_SIZE * 2];
}CLILIST;

typedef     CLILIST FAR *LPCLILIST;
typedef     CLILIST     *PCLILIST;


// this is an object to be embedded in both CDefClient and CDDEServer to glue
// to the new(est) call control interface
class CDdeServerCallMgr : public IRpcStubBuffer, public IRpcChannelBuffer2 {

   private:
   	CDefClient * m_pDefClient;	// our embeddor (either a CDefClient or a CDDEServer)
	CDDEServer * m_pDDEServer;	// one of these is NULL;

   public:
	CDdeServerCallMgr (CDefClient * pDefClient)
           { m_pDefClient       = pDefClient; 
             m_pDDEServer 	= NULL;}

	CDdeServerCallMgr (CDDEServer * pDefClient)
           { m_pDefClient       = NULL; 
             m_pDDEServer 	= pDefClient;}

	STDMETHOD(QueryInterface) ( REFIID iid, LPVOID * ppvObj);
	STDMETHOD_(ULONG,AddRef) ();
	STDMETHOD_(ULONG,Release) ();

	// IRpcStubBuffer methods
	STDMETHOD(Connect)(
            /* [in] */ IUnknown *pUnkServer);
        
        STDMETHOD_(void,Disconnect)( void);
        
        STDMETHOD(Invoke)( 
            /* [in] */ RPCOLEMESSAGE *_prpcmsg,
            /* [in] */ IRpcChannelBuffer *_pRpcChannelBuffer);
        
        STDMETHOD_(IRpcStubBuffer *,IsIIDSupported)( 
            /* [in] */ REFIID riid);
        
	STDMETHOD_(ULONG,CountRefs)( void);
        
        STDMETHOD(DebugServerQueryInterface)( 
            void * *ppv);
        
        STDMETHOD_(void,DebugServerRelease)( 
            void  *pv);



	 // IRpcChannelBuffer methods
        STDMETHOD(GetBuffer) ( 
            /* [in] */ RPCOLEMESSAGE __RPC_FAR *pMessage,
            /* [in] */ REFIID riid);
        
        STDMETHOD(SendReceive) ( 
            /* [out][in] */ RPCOLEMESSAGE __RPC_FAR *pMessage,
            /* [out] */ ULONG __RPC_FAR *pStatus);
        
        STDMETHOD(FreeBuffer) ( 
            /* [in] */ RPCOLEMESSAGE __RPC_FAR *pMessage);
        
        STDMETHOD(GetDestCtx) ( 
            /* [out] */ DWORD __RPC_FAR *pdwDestContext,
            /* [out] */ void __RPC_FAR *__RPC_FAR *ppvDestContext);
        
        STDMETHOD(IsConnected) ( void);

	STDMETHOD(SendReceive2) (
            /* [out][in] */ RPCOLEMESSAGE __RPC_FAR *pMessage,
            /* [out] */ ULONG __RPC_FAR *pStatus);
};


class FAR CDDEServer
{
  public:
    static HRESULT 	Create (LPOLESTR lpclass,
			    	REFCLSID rclsid,
			    	LPDDECLASSINFO lpDdeInfo,
				HWND FAR * phwnd,
				ATOM aOriginalClass,
				CNVTYP cnvtyp);

    INTERNAL_(BOOL)	HandleInitMsg (LPARAM);
    INTERNAL    	SrvrExecute (HWND, HANDLE, HWND);
    INTERNAL    	Revoke (void);
    INTERNAL_(BOOL)	QueryRevokeClassFactory (void);
    INTERNAL_(LPCLIENT) FindDocObj (LPSTR lpDoc);
    INTERNAL_(void)	Lock (BOOL fLock, HWND hwndClient);


    CLSID	    m_clsid;		  // Class ID
    DWORD	    m_dwClassFactoryKey;  // Class factory reg key
    LPCLASSFACTORY  m_pClassFactory;      // class factory
    CDdeServerCallMgr m_pCallMgr;	  // call management interfaces
    BOOL            m_bTerminate;         // Set if we are terminating.
    HWND            m_hwnd;               // corresponding window
    HANDLE          m_hcli;               // handle to the first block of clients list
    int             m_termNo;             // termination count
    int             m_cSrvrClients;       // no of clients;
    DWORD           m_fcfFlags;           // Class factory instance usage flags
    CNVTYP	    m_cnvtyp;			
    CHK		    m_chk;

    ATOM            m_aClass;             // class atom
    ATOM            m_aOriginalClass;     // for TreatAs/ConvertTo case
    ATOM            m_aExe;

    BOOL	    m_fDoNotDestroyWindow; // When set, server wnd ingores WM_USER

  private:
    INTERNAL_(void)     SendServerTerminateMsg (void);
    INTERNAL		RevokeAllDocObjs (void);
    INTERNAL		FreeSrvrMem (void);
    INTERNAL		CreateInstance (REFCLSID clsid, LPOLESTR lpWidedocName, LPSTR lpdocName,
					LPUNKNOWN pUnk, LPCLIENT FAR* lplpdocClient,
					HWND hwndClient);

public:
    //ctor
    CDDEServer()
    		: m_pCallMgr( this )
    	{
	}


};




BOOL              SendInitMsgToChildren (HWND, UINT msg, WPARAM wParam, LPARAM lParam);

INTERNAL	  RequestDataStd (ATOM, HANDLE FAR *);
INTERNAL_(BOOL)   ValidateSrvrClass (LPOLESTR, ATOM FAR *);
INTERNAL_(ATOM)   GetExeAtom (LPOLESTR);
INTERNAL_(BOOL)   AddClient (LPHANDLE, HANDLE, HANDLE);
INTERNAL_(HANDLE) FindClient (HANDLE hCli, HANDLE hkey, BOOL fDelete);

INTERNAL_(BOOL)   IsSingleServerInstance (void);

INTERNAL_(void)   UtilMemCpy (LPSTR, LPSTR, DWORD);
INTERNAL_(HANDLE) DuplicateData (HANDLE);
INTERNAL_(LPSTR)  ScanBoolArg (LPSTR, BOOL FAR *);
INTERNAL_(LPSTR)  ScanNumArg (LPSTR, LPINT);
INTERNAL_(LPSTR)  ScanArg(LPSTR);
INTERNAL_(ATOM)   MakeDataAtom (ATOM, int);
INTERNAL_(ATOM)   DuplicateAtom (ATOM);
INTERNAL_(BOOL)   CLSIDFromAtom(ATOM aClass, LPCLSID lpclsid);
INTERNAL	  CLSIDFromAtomWithTreatAs (ATOM FAR* paClass, LPCLSID lpclsid,
					    CNVTYP FAR* pcnvtyp);
INTERNAL	  wFileIsRunning (LPOLESTR szFile);
INTERNAL	  wFileBind (LPOLESTR szFile, LPUNKNOWN FAR* ppUnk);
INTERNAL	  wCreateStgAroundNative (HANDLE hNative,
					ATOM aClassOld,
					ATOM aClassNew,
					CNVTYP cnvtyp,
					ATOM aItem,
					LPSTORAGE FAR* ppstg,
					LPLOCKBYTES FAR* pplkbyt);
INTERNAL	  wCompatibleClasses (ATOM aClient, ATOM aSrvr);




typedef struct FARSTRUCT : public CPrivAlloc {
	BOOL	f;	    // do we need to send an ack?
			    // If this is FALSE, other fields don't matter
	HGLOBAL hdata;
	HWND	hwndFrom;   // who sent the execute?
	HWND	hwndTo;
} EXECUTEACK;


// client struct definitions.



class FAR CDefClient : public CPrivAlloc
{
  public:
	static INTERNAL Create
			       (LPSRVR	    pDdeSrvr,
				LPUNKNOWN   lpunkObj,
				LPOLESTR    lpdocName,
				const BOOL  fSetClientSite,
				const BOOL  fDoAdvise,
				const BOOL  fRunningInSDI = FALSE,
				HWND FAR*   phwnd = NULL);

   INTERNAL         DocExecute (HANDLE);
   INTERNAL         DocDoVerbItem (LPSTR, WORD, BOOL, BOOL);
   INTERNAL         DocShowItem (LPSTR, BOOL);
   INTERNAL         DestroyInstance ();
   INTERNAL_(void)  DeleteFromItemsList (HWND h);
   INTERNAL_(void)  RemoveItemFromItemList (void);
   INTERNAL_(void)  ReleasePseudoItems (void);
   INTERNAL_(void)  ReleaseAllItems ();
   INTERNAL         PokeStdItems (HWND, ATOM, HANDLE,int);
   INTERNAL         PokeData (HWND, ATOM, HANDLE);
   INTERNAL         AdviseData (HWND, ATOM, HANDLE, BOOL FAR *);
   INTERNAL         AdviseStdItems (HWND, ATOM, HANDLE, BOOL FAR *);
   INTERNAL         UnAdviseData (HWND, ATOM);
   INTERNAL         RequestData (HWND, ATOM, USHORT, HANDLE FAR *);
   INTERNAL         Revoke (BOOL fRelease=TRUE);
   INTERNAL	    ReleaseObjPtrs (void);
   INTERNAL_(void)  DeleteAdviseInfo ();
   INTERNAL	    DoOle20Advise (OLE_NOTIFICATION, CLIPFORMAT);
   INTERNAL	    DoOle20UnAdviseAll (void);
   INTERNAL	    SetClientSite (void);
   INTERNAL	    NoItemConnections (void);
   INTERNAL_(void)  SendExecuteAck (HRESULT hresult);
   INTERNAL	    DoInitNew(void);
   INTERNAL	    Terminate(HWND, HWND);
   INTERNAL_(void)  SetCallState (SERVERCALLEX State)
		    {
			m_CallState = State;
		    }

	CHK		  m_chk;       // signature
	CDdeServerCallMgr m_pCallMgr;  // call management interfaces
	SERVERCALLEX	  m_CallState;

	IUnknown FAR*	m_pUnkOuter;
	LPOLEOBJECT     m_lpoleObj;    // corresponding oleobj
	LPDATAOBJECT	m_lpdataObj;   // corresponding dataobj
	BOOL            m_bCreateInst; // instance is just created.
	BOOL            m_bTerminate;  // REVIEW: The next two fields may not be necessary.
	int             m_termNo;
	ATOM            m_aItem;       // item atom or index for some std items
	HANDLE          m_hcli;        // handle to the first block of clients list (Document only)
	CDefClient FAR *m_lpNextItem;  // ptr to the next item.
	BOOL            m_bContainer;  // Is document?
	BOOL            m_cRef;
	HWND            m_hwnd;        // doc window (only needed in document)
	HANDLE          m_hdevInfo;    // latest printer dev info sent
	HANDLE          m_hcliInfo;    // advise info for each of the clients
	BOOL		m_fDidRealSetHostNames;
	BOOL		m_fDidSetClientSite;
	BOOL		m_fGotDdeAdvise;
	BOOL		m_fCreatedNotConnected;
	BOOL		m_fInOnClose;
	BOOL		m_fInOleSave;
	EXECUTEACK	m_ExecuteAck;
	DWORD		m_dwConnectionOleObj;
	DWORD		m_dwConnectionDataObj;
	LPLOCKBYTES	m_plkbytNative; // These two fields always refer to
	LPSTORAGE	m_pstgNative;	//   to the same bits:
					// The server's persistent storage is
					// used as its native data.
	BOOL		m_fRunningInSDI;// Link case: file was already open in
					// an SDI app which does not register a
					// class factory.
	LPSRVR		m_psrvrParent;	// (Document only)
	DVTARGETDEVICE FAR* m_ptd;
	BOOL		m_fGotStdCloseDoc;
	BOOL		m_fGotEditNoPokeNativeYet;
	BOOL		m_fLocked; // locked by CoLockObjectExternal ?

	// If not FALSE, then we are waiting for a matching TERMINATE

	BOOL		m_fCallData;





	// REVIEW: These fields might be necssary for doc (old) level object
   	BOOL          	m_fEmbed;      	// embedded object (Document only)
	int		m_cClients;	// (Document only)
	LPCLIENT	m_pdoc; 	// containing document (for items) or self (for docs)


implementations:

	STDUNKDECL (CDefClient,DefClient);

	/*** IOleClientSite ***/
	implement COleClientSiteImpl : IOleClientSite
	{
		public:
		// Constructor
		COleClientSiteImpl (CDefClient FAR* pDefClient)
		{	m_pDefClient = pDefClient;
		}
		STDMETHOD(QueryInterface) (REFIID, LPVOID FAR *);
		STDMETHOD_(ULONG,AddRef) (void);
		STDMETHOD_(ULONG,Release) (void);

		/*** IOleClientSite methods ***/
		STDMETHOD(SaveObject) (THIS);
		STDMETHOD(GetMoniker) (THIS_ DWORD dwAssign, DWORD dwWhichMoniker,
					LPMONIKER FAR* ppmk);
		STDMETHOD(GetContainer) (THIS_ LPOLECONTAINER FAR* ppContainer);
		STDMETHOD(ShowObject) (THIS);
		STDMETHOD(OnShowWindow) (THIS_ BOOL fShow);
		STDMETHOD(RequestNewObjectLayout) (THIS);
		
		private:
		CDefClient FAR* m_pDefClient;
	};

	DECLARE_NC (CDefClient, COleClientSiteImpl)
	COleClientSiteImpl m_OleClientSite;



	/*** IAdviseSink ***/
	implement CAdviseSinkImpl : IAdviseSink
	{
		public:
		// Constructor
		CAdviseSinkImpl (CDefClient FAR* pDefClient)
		{	m_pDefClient = pDefClient;
		}

		STDMETHOD(QueryInterface) (REFIID, LPVOID FAR *);
		STDMETHOD_(ULONG,AddRef) (void);
		STDMETHOD_(ULONG,Release) (void);

		/**** IAdviseSink methods ****/
		STDMETHOD_(void,OnDataChange)(THIS_ FORMATETC FAR* pFormatetc,
												STGMEDIUM FAR* pStgmed) ;
		STDMETHOD_(void,OnViewChange)(THIS_ DWORD aspects, LONG lindex) ;
		STDMETHOD_(void,OnExtentChange)(DWORD dwAspect, LPSIZEL lpsizel) {}
		STDMETHOD_(void,OnRename)(THIS_ LPMONIKER pmk) ;
		STDMETHOD_(void,OnSave)(THIS) ;
		STDMETHOD_(void,OnClose)(THIS) ;

		private:
		CDefClient FAR* m_pDefClient;
	};


	DECLARE_NC (CDefClient, CAdviseSinkImpl)

	CAdviseSinkImpl m_AdviseSink;
ctor_dtor:
	CDefClient (LPUNKNOWN pUnkOuter);
	~CDefClient (void);

private:
	INTERNAL            ItemCallBack (int msg, LPOLESTR szNewName = NULL);
	INTERNAL_(void)     SendTerminateMsg ();
	INTERNAL_(BOOL)     SendDataMsg1 (HANDLE, WORD);
	INTERNAL_(BOOL)     SendDataMsg (WORD);
	INTERNAL_(void)     TerminateNonRenameClients (LPCLIENT);
	INTERNAL_(void)     SendRenameMsgs (HANDLE);
	INTERNAL            RegisterItem (LPOLESTR, LPCLIENT FAR *, BOOL);
	INTERNAL            FindItem (LPOLESTR, LPCLIENT FAR *);
	INTERNAL_(LPCLIENT) SearchItem (LPOLESTR);
	INTERNAL_(void)     DeleteAllItems ();
	INTERNAL            SetStdInfo (HWND, LPOLESTR, HANDLE);
	INTERNAL_(void)     SendDevInfo (HWND);
	INTERNAL_(BOOL)     IsFormatAvailable (CLIPFORMAT);
	INTERNAL	    GetData (LPFORMATETC, LPSTGMEDIUM);
};




typedef struct _CLINFO : public CPrivAlloc { /*clInfo*/ // client transaction info
    HWND        hwnd;               // client window handle
    BOOL        bnative;            // doe sthis client require native
    int         format;             // dusplay format
    int         options;            // transaction advise time otipns
    BOOL        bdata;              // need wdat with advise?
    HANDLE      hdevInfo;           // device info handle
    BOOL        bnewDevInfo;        // new device info
} CLINFO;

typedef  CLINFO  *PCLINFO;



INTERNAL_(BOOL)   MakeDDEData (HANDLE, int, LPHANDLE, BOOL);
INTERNAL_(HANDLE) MakeGlobal (LPSTR);
INTERNAL          ScanItemOptions (LPOLESTR, int far *);
INTERNAL_(int)    GetStdItemIndex (ATOM);
INTERNAL_(BOOL)   IsAdviseStdItems (ATOM);
INTERNAL_(HANDLE) MakeItemData (DDEPOKE FAR *, HANDLE, CLIPFORMAT);
INTERNAL_(BOOL)   AddMessage (HWND, unsigned, WORD, LONG, int);



#define     ITEM_FIND          1      // find the item
#define     ITEM_DELETECLIENT  2      // delete the client from item clients
#define     ITEM_DELETE        3      // delete th item window itself
#define     ITEM_SAVED         4      // item saved

// host names data structcure
typedef struct _HOSTNAMES : public CPrivAlloc {
    WORD    clientNameOffset;
    WORD    documentNameOffset;
    BYTE    data[1];
} HOSTNAMES;

typedef HOSTNAMES FAR * LPHOSTNAMES;


// routines in UTILS.C
LPOLESTR CreateUnicodeFromAnsi( LPCSTR lpAnsi);
LPSTR CreateAnsiFromUnicode( LPCOLESTR lpAnsi);
INTERNAL_(HANDLE) DuplicateData (HANDLE);
INTERNAL_(LPSTR)  ScanLastBoolArg (LPSTR);
INTERNAL_(LPSTR)  ScanArg(LPSTR);
INTERNAL_(WORD)   ScanCommand(LPSTR, WORD, LPSTR FAR *, ATOM FAR *);
INTERNAL_(ATOM)   MakeDataAtom (ATOM, int);
INTERNAL_(ATOM)   DuplicateAtom (ATOM);
INTERNAL_(WORD)   StrToInt (LPOLESTR);
INTERNAL_(BOOL)   PostMessageToClientWithReply (HWND, UINT, WPARAM, LPARAM, UINT);
INTERNAL_(BOOL)   PostMessageToClient (HWND, UINT, WPARAM, LPARAM);
INTERNAL_(BOOL)   IsWindowValid (HWND);
INTERNAL_(BOOL)   IsOleCommand (ATOM, WORD);
INTERNAL_(BOOL)   UtilQueryProtocol (ATOM, LPOLESTR);
INTERNAL	  SynchronousPostMessage (HWND, UINT, WPARAM, LPARAM);
INTERNAL_(BOOL)   IsAtom (ATOM);
INTERNAL_(BOOL)   IsFile (ATOM a, BOOL FAR* pfUnsavedDoc = NULL);


// routines for queueing messages and posting them
INTERNAL_(BOOL)        UnblockPostMsgs(HWND, BOOL);
INTERNAL_(BOOL)        BlockPostMsg (HWND, WORD, WORD, LONG);
INTERNAL_(BOOL)        IsBlockQueueEmpty (HWND);

// routine in GIVE2GDI.ASM
extern "C" HANDLE  FAR PASCAL  GiveToGDI (HANDLE);


// routine in item.c
INTERNAL_(HBITMAP)     DuplicateBitmap (HBITMAP);
INTERNAL_(HANDLE)      DuplicateMetaFile (HANDLE);
INTERNAL_(BOOL) AreNoClients (HANDLE hcli);
#ifdef _DEBUG
INTERNAL_(LPOLESTR) a2s (ATOM);
#endif

// routines in doc.c
INTERNAL_(void)        FreePokeData (HANDLE);
INTERNAL_(BOOL)        FreeGDIdata (HANDLE, CLIPFORMAT);
INTERNAL DdeHandleIncomingCall(HWND hwndCli, WORD wCallType);


// in ddeworkr.cpp
INTERNAL_(HANDLE) wNewHandle (LPSTR lpstr, DWORD cb);
INTERNAL wTimedGetMessage (LPMSG pmsg, HWND hwnd, WORD wFirst, WORD wLast);
INTERNAL_(ATOM) wGlobalAddAtom (LPCOLESTR sz);

//+---------------------------------------------------------------------------
//
//  Function:   TLSSetDdeServer
//
//  Synopsis:   Sets hwnd to CommonDdeServer window
//
//  Arguments:  [hwndDdeServer] --
//
//  History:    5-13-94   kevinro   Created
//
//  Notes:
//
//----------------------------------------------------------------------------
inline BOOL TLSSetDdeServer(HWND hwndDdeServer)
{
    HRESULT hr;
    COleTls tls(hr);

    if (SUCCEEDED(hr))
    {
	tls->hwndDdeServer = hwndDdeServer;
        return TRUE;
    }

    return FALSE;
}

//+---------------------------------------------------------------------------
//
//  Function:   TLSGetDdeServer
//
//  Synopsis:   Returns a handle to the per thread DdeServer window
//
//  Returns:    hwndDdeServer for thread
//
//  History:    5-13-94   kevinro   Created
//
//  Notes:
//----------------------------------------------------------------------------
inline HWND TLSGetDdeServer()
{
    HRESULT hr;
    COleTls tls(hr);

    if (SUCCEEDED(hr))
    {
	return tls->hwndDdeServer;
    }

    return NULL;
}