source: trunk/src/ole32/filemoniker.c@ 6666

Last change on this file since 6666 was 6648, checked in by bird, 24 years ago

Added $Id:$ keyword.

File size: 42.7 KB
Line 
1/* $Id: filemoniker.c,v 1.2 2001-09-05 13:17:09 bird Exp $ */
2/***************************************************************************************
3 * FileMonikers implementation
4 *
5 * Copyright 1999 Noomen Hamza
6 ***************************************************************************************/
7
8#include <assert.h>
9#include <string.h>
10#include "winbase.h"
11#include "winerror.h"
12#include "winnls.h"
13#include "wine/unicode.h"
14#include "debugtools.h"
15#include "objbase.h"
16#include "wine/obj_storage.h"
17#include "wine/obj_moniker.h"
18#include "wine/obj_base.h"
19
20#include "compobj_private.h"
21
22DEFAULT_DEBUG_CHANNEL(ole);
23
24/* filemoniker data structure */
25typedef struct FileMonikerImpl{
26
27 ICOM_VTABLE(IMoniker)* lpvtbl1; /* VTable relative to the IMoniker interface.*/
28
29 /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
30 * two monikers are equal. That's whay IROTData interface is implemented by monikers.
31 */
32 ICOM_VTABLE(IROTData)* lpvtbl2; /* VTable relative to the IROTData interface.*/
33
34 ULONG ref; /* reference counter for this object */
35
36 LPOLESTR filePathName; /* path string identified by this filemoniker */
37
38} FileMonikerImpl;
39
40/********************************************************************************/
41/* FileMoniker prototype functions : */
42
43/* IUnknown prototype functions */
44static HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
45static ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface);
46static ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface);
47
48/* IPersist prototype functions */
49static HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
50
51/* IPersistStream prototype functions */
52static HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface);
53static HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface, IStream* pStm);
54static HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
55static HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
56
57/* IMoniker prototype functions */
58static HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
59static HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
60static HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
61static HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
62static HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
63static HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
64static HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
65static HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
66static HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pFileTime);
67static HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
68static HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
69static HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
70static HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
71static HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
72static HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
73
74/********************************************************************************/
75/* IROTData prototype functions */
76
77/* IUnknown prototype functions */
78static HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
79static ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData* iface);
80static ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface);
81
82/* IROTData prototype function */
83static HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
84
85/* Local function used by filemoniker implementation */
86HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
87HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface);
88int WINAPI FileMonikerImpl_DecomposePath(LPOLESTR str, LPOLESTR** tabStr);
89
90
91/********************************************************************************/
92/* Virtual function table for the FileMonikerImpl class which include IPersist,*/
93/* IPersistStream and IMoniker functions. */
94static ICOM_VTABLE(IMoniker) VT_FileMonikerImpl =
95{
96 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
97 FileMonikerImpl_QueryInterface,
98 FileMonikerImpl_AddRef,
99 FileMonikerImpl_Release,
100 FileMonikerImpl_GetClassID,
101 FileMonikerImpl_IsDirty,
102 FileMonikerImpl_Load,
103 FileMonikerImpl_Save,
104 FileMonikerImpl_GetSizeMax,
105 FileMonikerImpl_BindToObject,
106 FileMonikerImpl_BindToStorage,
107 FileMonikerImpl_Reduce,
108 FileMonikerImpl_ComposeWith,
109 FileMonikerImpl_Enum,
110 FileMonikerImpl_IsEqual,
111 FileMonikerImpl_Hash,
112 FileMonikerImpl_IsRunning,
113 FileMonikerImpl_GetTimeOfLastChange,
114 FileMonikerImpl_Inverse,
115 FileMonikerImpl_CommonPrefixWith,
116 FileMonikerImpl_RelativePathTo,
117 FileMonikerImpl_GetDisplayName,
118 FileMonikerImpl_ParseDisplayName,
119 FileMonikerImpl_IsSystemMoniker
120};
121
122/********************************************************************************/
123/* Virtual function table for the IROTData class. */
124static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
125{
126 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
127 FileMonikerROTDataImpl_QueryInterface,
128 FileMonikerROTDataImpl_AddRef,
129 FileMonikerROTDataImpl_Release,
130 FileMonikerROTDataImpl_GetComparaisonData
131};
132
133/*******************************************************************************
134 * FileMoniker_QueryInterface
135 *******************************************************************************/
136HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
137{
138 ICOM_THIS(FileMonikerImpl,iface);
139
140 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
141
142 /* Perform a sanity check on the parameters.*/
143 if ( (This==0) || (ppvObject==0) )
144 return E_INVALIDARG;
145
146 /* Initialize the return parameter */
147 *ppvObject = 0;
148
149 /* Compare the riid with the interface IDs implemented by this object.*/
150 if (IsEqualIID(&IID_IUnknown, riid) ||
151 IsEqualIID(&IID_IPersist, riid) ||
152 IsEqualIID(&IID_IPersistStream,riid) ||
153 IsEqualIID(&IID_IMoniker, riid)
154 )
155 *ppvObject = iface;
156
157 else if (IsEqualIID(&IID_IROTData, riid))
158 *ppvObject = (IROTData*)&(This->lpvtbl2);
159
160 /* Check that we obtained an interface.*/
161 if ((*ppvObject)==0)
162 return E_NOINTERFACE;
163
164 /* Query Interface always increases the reference count by one when it is successful */
165 FileMonikerImpl_AddRef(iface);
166
167 return S_OK;
168}
169
170/******************************************************************************
171 * FileMoniker_AddRef
172 ******************************************************************************/
173ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface)
174{
175 ICOM_THIS(FileMonikerImpl,iface);
176
177 TRACE("(%p)\n",iface);
178
179 return ++(This->ref);
180}
181
182/******************************************************************************
183 * FileMoniker_Release
184 ******************************************************************************/
185ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface)
186{
187 ICOM_THIS(FileMonikerImpl,iface);
188
189 TRACE("(%p)\n",iface);
190
191 This->ref--;
192
193 /* destroy the object if there's no more reference on it */
194 if (This->ref==0){
195
196 FileMonikerImpl_Destroy(This);
197
198 return 0;
199 }
200 return This->ref;;
201}
202
203/******************************************************************************
204 * FileMoniker_GetClassID
205 ******************************************************************************/
206HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface,
207 CLSID *pClassID)/* Pointer to CLSID of object */
208{
209 TRACE("(%p,%p),stub!\n",iface,pClassID);
210
211 if (pClassID==NULL)
212 return E_POINTER;
213
214 *pClassID = CLSID_FileMoniker;
215
216 return S_OK;
217}
218
219/******************************************************************************
220 * FileMoniker_IsDirty
221 ******************************************************************************/
222HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface)
223{
224 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
225 method in the OLE-provided moniker interfaces always return S_FALSE because
226 their internal state never changes. */
227
228 TRACE("(%p)\n",iface);
229
230 return S_FALSE;
231}
232
233/******************************************************************************
234 * FileMoniker_Load
235 ******************************************************************************/
236HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
237{
238 HRESULT res;
239 CHAR* filePathA;
240 WCHAR* filePathW;
241 ULONG bread;
242 WORD wbuffer;
243 DWORD dwbuffer,length,i,doubleLenHex,doubleLenDec;
244
245 ICOM_THIS(FileMonikerImpl,iface);
246
247 TRACE("(%p,%p)\n",iface,pStm);
248
249 /* this function locates and reads from the stream the filePath string written by FileMonikerImpl_Save */
250
251 /* first WORD is non significative */
252 res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
253 if (bread!=sizeof(WORD) || wbuffer!=0)
254 return E_FAIL;
255
256 /* read filePath string length (plus one) */
257 res=IStream_Read(pStm,&length,sizeof(DWORD),&bread);
258 if (bread != sizeof(DWORD))
259 return E_FAIL;
260
261 /* read filePath string */
262 filePathA=HeapAlloc(GetProcessHeap(),0,length);
263 res=IStream_Read(pStm,filePathA,length,&bread);
264 if (bread != length)
265 return E_FAIL;
266
267 /* read the first constant */
268 IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
269 if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
270 return E_FAIL;
271
272 length--;
273
274 for(i=0;i<10;i++){
275 res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
276 if (bread!=sizeof(WORD) || wbuffer!=0)
277 return E_FAIL;
278 }
279
280 if (length>8)
281 length=0;
282
283 doubleLenHex=doubleLenDec=2*length;
284 if (length > 5)
285 doubleLenDec+=6;
286
287 res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
288 if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenDec)
289 return E_FAIL;
290
291 if (length==0)
292 return res;
293
294 res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
295 if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenHex)
296 return E_FAIL;
297
298 res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
299 if (bread!=sizeof(WORD) || wbuffer!=0x3)
300 return E_FAIL;
301
302 filePathW=HeapAlloc(GetProcessHeap(),0,(length+1)*sizeof(WCHAR));
303 filePathW[length]=0;
304 res=IStream_Read(pStm,filePathW,doubleLenHex,&bread);
305 if (bread!=doubleLenHex)
306 return E_FAIL;
307
308 if (This->filePathName!=NULL)
309 HeapFree(GetProcessHeap(),0,This->filePathName);
310
311 This->filePathName=filePathW;
312
313 HeapFree(GetProcessHeap(),0,filePathA);
314
315 return res;
316}
317
318/******************************************************************************
319 * FileMoniker_Save
320 ******************************************************************************/
321HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface,
322 IStream* pStm,/* pointer to the stream where the object is to be saved */
323 BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
324{
325 /* this function saves data of this object. In the begining I thougth that I have just to write
326 * the filePath string on Stream. But, when I tested this function whith windows programs samples !
327 * I noted that it was not the case. So I analysed data written by this function on Windows system and
328 * what did this function do exactly ! but I have no idear a bout its logic !
329 * I guessed data who must be written on stream wich is:
330 * 1) WORD constant:zero 2) length of the path string ("\0" included) 3) path string type A
331 * 4) DWORD constant : 0xDEADFFFF 5) ten WORD constant: zero 6) DWORD: double-length of the the path
332 * string type W ("\0" not included) 7) WORD constant: 0x3 8) filePath unicode string.
333 * if the length(filePath) > 8 or.length(filePath) == 8 stop at step 5)
334 */
335
336 ICOM_THIS(FileMonikerImpl,iface);
337
338 HRESULT res;
339 LPOLESTR filePathW=This->filePathName;
340 CHAR* filePathA;
341 DWORD len;
342
343 DWORD constant1 = 0xDEADFFFF; /* these constants are detected after analysing the data structure written by */
344 WORD constant2 = 0x3; /* FileMoniker_Save function in a windows program system */
345
346 WORD zero=0;
347 DWORD doubleLenHex;
348 DWORD doubleLenDec;
349 int i=0;
350
351 TRACE("(%p,%p,%d)\n",iface,pStm,fClearDirty);
352
353 if (pStm==NULL)
354 return E_POINTER;
355
356 /* write a DWORD set to 0 : constant */
357 res=IStream_Write(pStm,&zero,sizeof(WORD),NULL);
358
359 /* write length of filePath string ( "\0" included )*/
360 len = WideCharToMultiByte( CP_ACP, 0, filePathW, -1, NULL, 0, NULL, NULL );
361 res=IStream_Write(pStm,&len,sizeof(DWORD),NULL);
362
363 /* write filePath string type A */
364 filePathA=HeapAlloc(GetProcessHeap(),0,len);
365 WideCharToMultiByte( CP_ACP, 0, filePathW, -1, filePathA, len, NULL, NULL );
366 res=IStream_Write(pStm,filePathA,len,NULL);
367 HeapFree(GetProcessHeap(),0,filePathA);
368
369 /* write a DWORD set to 0xDEADFFFF: constant */
370 res=IStream_Write(pStm,&constant1,sizeof(DWORD),NULL);
371
372 len--;
373 /* write 10 times a DWORD set to 0 : constants */
374 for(i=0;i<10;i++)
375 res=IStream_Write(pStm,&zero,sizeof(WORD),NULL);
376
377 if (len>8)
378 len=0;
379
380 doubleLenHex=doubleLenDec=2*len;
381 if (len > 5)
382 doubleLenDec+=6;
383
384 /* write double-length of the path string ( "\0" included )*/
385 res=IStream_Write(pStm,&doubleLenDec,sizeof(DWORD),NULL);
386
387 if (len==0)
388 return res;
389
390 /* write double-length (hexa representation) of the path string ( "\0" included ) */
391 res=IStream_Write(pStm,&doubleLenHex,sizeof(DWORD),NULL);
392
393 /* write a WORD set to 0x3: constant */
394 res=IStream_Write(pStm,&constant2,sizeof(WORD),NULL);
395
396 /* write path unicode string */
397 res=IStream_Write(pStm,filePathW,doubleLenHex,NULL);
398
399 return res;
400}
401
402/******************************************************************************
403 * FileMoniker_GetSizeMax
404 ******************************************************************************/
405HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
406 ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
407{
408 ICOM_THIS(FileMonikerImpl,iface);
409 DWORD len=lstrlenW(This->filePathName);
410 DWORD sizeMAx;
411
412 TRACE("(%p,%p)\n",iface,pcbSize);
413
414 if (pcbSize!=NULL)
415 return E_POINTER;
416
417 /* for more details see FileMonikerImpl_Save coments */
418
419 sizeMAx = sizeof(WORD) + /* first WORD is 0 */
420 sizeof(DWORD)+ /* length of filePath including "\0" in the end of the string */
421 (len+1)+ /* filePath string */
422 sizeof(DWORD)+ /* constant : 0xDEADFFFF */
423 10*sizeof(WORD)+ /* 10 zero WORD */
424 sizeof(DWORD); /* size of the unicode filePath: "\0" not included */
425
426 if (len==0 || len > 8)
427 return S_OK;
428
429 sizeMAx += sizeof(DWORD)+ /* size of the unicode filePath: "\0" not included */
430 sizeof(WORD)+ /* constant : 0x3 */
431 len*sizeof(WCHAR); /* unicde filePath string */
432
433 pcbSize->s.LowPart=sizeMAx;
434 pcbSize->s.HighPart=0;
435
436 return S_OK;
437}
438
439/******************************************************************************
440 * FileMoniker_Construct (local function)
441 *******************************************************************************/
442HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPathName)
443{
444 int nb=0,i;
445 int sizeStr=lstrlenW(lpszPathName);
446 LPOLESTR *tabStr=0;
447 WCHAR twoPoint[]={'.','.',0};
448 WCHAR bkSlash[]={'\\',0};
449 BYTE addBkSlash;
450
451 TRACE("(%p,%p)\n",This,lpszPathName);
452
453 /* Initialize the virtual fgunction table. */
454 This->lpvtbl1 = &VT_FileMonikerImpl;
455 This->lpvtbl2 = &VT_ROTDataImpl;
456 This->ref = 0;
457
458 This->filePathName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr+1));
459
460 if (This->filePathName==NULL)
461 return E_OUTOFMEMORY;
462
463 strcpyW(This->filePathName,lpszPathName);
464
465 nb=FileMonikerImpl_DecomposePath(This->filePathName,&tabStr);
466
467 if (nb > 0 ){
468
469 addBkSlash=1;
470 if (lstrcmpW(tabStr[0],twoPoint)!=0)
471 addBkSlash=0;
472 else
473 for(i=0;i<nb;i++){
474
475 if ( (lstrcmpW(tabStr[i],twoPoint)!=0) && (lstrcmpW(tabStr[i],bkSlash)!=0) ){
476 addBkSlash=0;
477 break;
478 }
479 else
480
481 if (lstrcmpW(tabStr[i],bkSlash)==0 && i<nb-1 && lstrcmpW(tabStr[i+1],bkSlash)==0){
482 *tabStr[i]=0;
483 sizeStr--;
484 addBkSlash=0;
485 break;
486 }
487 }
488
489 if (lstrcmpW(tabStr[nb-1],bkSlash)==0)
490 addBkSlash=0;
491
492 This->filePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR));
493
494 *This->filePathName=0;
495
496 for(i=0;tabStr[i]!=NULL;i++)
497 strcatW(This->filePathName,tabStr[i]);
498
499 if (addBkSlash)
500 strcatW(This->filePathName,bkSlash);
501 }
502
503 for(i=0; tabStr[i]!=NULL;i++)
504 CoTaskMemFree(tabStr[i]);
505 CoTaskMemFree(tabStr);
506
507 return S_OK;
508}
509
510/******************************************************************************
511 * FileMoniker_Destroy (local function)
512 *******************************************************************************/
513HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This)
514{
515 TRACE("(%p)\n",This);
516
517 if (This->filePathName!=NULL)
518 HeapFree(GetProcessHeap(),0,This->filePathName);
519
520 HeapFree(GetProcessHeap(),0,This);
521
522 return S_OK;
523}
524
525/******************************************************************************
526 * FileMoniker_BindToObject
527 ******************************************************************************/
528HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,
529 IBindCtx* pbc,
530 IMoniker* pmkToLeft,
531 REFIID riid,
532 VOID** ppvResult)
533{
534 HRESULT res=E_FAIL;
535 CLSID clsID;
536 IUnknown* pObj=0;
537 IRunningObjectTable *prot=0;
538 IPersistFile *ppf=0;
539 IClassFactory *pcf=0;
540 IClassActivator *pca=0;
541
542 ICOM_THIS(FileMonikerImpl,iface);
543
544 *ppvResult=0;
545
546 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
547
548 if(pmkToLeft==NULL){
549
550 res=IBindCtx_GetRunningObjectTable(pbc,&prot);
551
552 if (SUCCEEDED(res)){
553 /* if the requested class was loaded befor ! we dont need to reload it */
554 res = IRunningObjectTable_GetObject(prot,iface,&pObj);
555
556 if (res==S_FALSE){
557 /* first activation of this class */
558 res=GetClassFile(This->filePathName,&clsID);
559 if (SUCCEEDED(res)){
560
561 res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IPersistFile,(void**)&ppf);
562 if (SUCCEEDED(res)){
563
564 res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
565 if (SUCCEEDED(res)){
566
567 pObj=(IUnknown*)ppf;
568 IUnknown_AddRef(pObj);
569 }
570 }
571 }
572 }
573 }
574 }
575 else{
576 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassFactory,(void**)&pcf);
577
578 if (res==E_NOINTERFACE){
579
580 res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassActivator,(void**)&pca);
581
582 if (res==E_NOINTERFACE)
583 return MK_E_INTERMEDIATEINTERFACENOTSUPPORTED;
584 }
585 if (pcf!=NULL){
586
587 IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)ppf);
588
589 res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
590
591 if (SUCCEEDED(res)){
592
593 pObj=(IUnknown*)ppf;
594 IUnknown_AddRef(pObj);
595 }
596 }
597 if (pca!=NULL){
598
599 FIXME("()");
600
601 /*res=GetClassFile(This->filePathName,&clsID);
602
603 if (SUCCEEDED(res)){
604
605 res=IClassActivator_GetClassObject(pca,&clsID,CLSCTX_ALL,0,&IID_IPersistFile,(void**)&ppf);
606
607 if (SUCCEEDED(res)){
608
609 pObj=(IUnknown*)ppf;
610 IUnknown_AddRef(pObj);
611 }
612 }*/
613 }
614}
615
616 if (pObj!=NULL){
617 /* get the requested interface from the loaded class */
618 res= IUnknown_QueryInterface(pObj,riid,ppvResult);
619
620 IBindCtx_RegisterObjectBound(pbc,(IUnknown*)*ppvResult);
621
622 IUnknown_Release(pObj);
623 }
624
625 if (prot!=NULL)
626 IRunningObjectTable_Release(prot);
627
628 if (ppf!=NULL)
629 IPersistFile_Release(ppf);
630
631 if (pca!=NULL)
632 IClassActivator_Release(pca);
633
634 if (pcf!=NULL)
635 IClassFactory_Release(pcf);
636
637 return res;
638}
639
640/******************************************************************************
641 * FileMoniker_BindToStorage
642 ******************************************************************************/
643HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
644 IBindCtx* pbc,
645 IMoniker* pmkToLeft,
646 REFIID riid,
647 VOID** ppvObject)
648{
649 LPOLESTR filePath=0;
650 IStorage *pstg=0;
651 HRESULT res;
652
653 TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject);
654
655 if (pmkToLeft==NULL){
656
657 if (IsEqualIID(&IID_IStorage, riid)){
658
659 /* get the file name */
660 FileMonikerImpl_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
661
662 /* verifie if the file contains a storage object */
663 res=StgIsStorageFile(filePath);
664
665 if(res==S_OK){
666
667 res=StgOpenStorage(filePath,NULL,STGM_READWRITE|STGM_SHARE_DENY_WRITE,NULL,0,&pstg);
668
669 if (SUCCEEDED(res)){
670
671 *ppvObject=pstg;
672
673 IStorage_AddRef(pstg);
674
675 return res;
676 }
677 }
678 CoTaskMemFree(filePath);
679 }
680 else
681 if ( (IsEqualIID(&IID_IStream, riid)) || (IsEqualIID(&IID_ILockBytes, riid)) )
682
683 return E_UNSPEC;
684 else
685
686 return E_NOINTERFACE;
687 }
688 else {
689
690 FIXME("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject);
691
692 return E_NOTIMPL;
693}
694 return res;
695}
696
697/******************************************************************************
698 * FileMoniker_Reduce
699 ******************************************************************************/
700HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,
701 IBindCtx* pbc,
702 DWORD dwReduceHowFar,
703 IMoniker** ppmkToLeft,
704 IMoniker** ppmkReduced)
705{
706 TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
707
708 if (ppmkReduced==NULL)
709 return E_POINTER;
710
711 FileMonikerImpl_AddRef(iface);
712
713 *ppmkReduced=iface;
714
715 return MK_S_REDUCED_TO_SELF;
716}
717/******************************************************************************
718 * FileMoniker_ComposeWith
719 ******************************************************************************/
720HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
721 IMoniker* pmkRight,
722 BOOL fOnlyIfNotGeneric,
723 IMoniker** ppmkComposite)
724{
725 HRESULT res;
726 LPOLESTR str1=0,str2=0,*strDec1=0,*strDec2=0,newStr=0;
727 WCHAR twoPoint[]={'.','.',0};
728 WCHAR bkSlash[]={'\\',0};
729 IBindCtx *bind=0;
730 int i=0,j=0,lastIdx1=0,lastIdx2=0;
731 DWORD mkSys;
732
733 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
734
735 if (ppmkComposite==NULL)
736 return E_POINTER;
737
738 if (pmkRight==NULL)
739 return E_INVALIDARG;
740
741 *ppmkComposite=0;
742
743 IMoniker_IsSystemMoniker(pmkRight,&mkSys);
744
745 /* check if we have two filemonikers to compose or not */
746 if(mkSys==MKSYS_FILEMONIKER){
747
748 CreateBindCtx(0,&bind);
749
750 FileMonikerImpl_GetDisplayName(iface,bind,NULL,&str1);
751 IMoniker_GetDisplayName(pmkRight,bind,NULL,&str2);
752
753 /* decompose pathnames of the two monikers : (to prepare the path merge operation ) */
754 lastIdx1=FileMonikerImpl_DecomposePath(str1,&strDec1)-1;
755 lastIdx2=FileMonikerImpl_DecomposePath(str2,&strDec2)-1;
756
757 if ((lastIdx1==-1 && lastIdx2>-1)||(lastIdx1==1 && lstrcmpW(strDec1[0],twoPoint)==0))
758 return MK_E_SYNTAX;
759
760 if(lstrcmpW(strDec1[lastIdx1],bkSlash)==0)
761 lastIdx1--;
762
763 /* for etch "..\" in the left of str2 remove the right element from str1 */
764 for(i=0; ( (lastIdx1>=0) && (strDec2[i]!=NULL) && (lstrcmpW(strDec2[i],twoPoint)==0) ) ;i+=2){
765
766 lastIdx1-=2;
767 }
768
769 /* the length of the composed path string is raised by the sum of the two paths lengths */
770 newStr=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(lstrlenW(str1)+lstrlenW(str2)+1));
771
772 if (newStr==NULL)
773 return E_OUTOFMEMORY;
774
775 /* new path is the concatenation of the rest of str1 and str2 */
776 for(*newStr=0,j=0;j<=lastIdx1;j++)
777 strcatW(newStr,strDec1[j]);
778
779 if ((strDec2[i]==NULL && lastIdx1>-1 && lastIdx2>-1) || lstrcmpW(strDec2[i],bkSlash)!=0)
780 strcatW(newStr,bkSlash);
781
782 for(j=i;j<=lastIdx2;j++)
783 strcatW(newStr,strDec2[j]);
784
785 /* create a new moniker with the new string */
786 res=CreateFileMoniker(newStr,ppmkComposite);
787
788 /* free all strings space memory used by this function */
789 HeapFree(GetProcessHeap(),0,newStr);
790
791 for(i=0; strDec1[i]!=NULL;i++)
792 CoTaskMemFree(strDec1[i]);
793 for(i=0; strDec2[i]!=NULL;i++)
794 CoTaskMemFree(strDec2[i]);
795 CoTaskMemFree(strDec1);
796 CoTaskMemFree(strDec2);
797
798 CoTaskMemFree(str1);
799 CoTaskMemFree(str2);
800
801 return res;
802 }
803 else if(mkSys==MKSYS_ANTIMONIKER){
804
805 *ppmkComposite=NULL;
806 return S_OK;
807 }
808 else if (fOnlyIfNotGeneric){
809
810 *ppmkComposite=NULL;
811 return MK_E_NEEDGENERIC;
812 }
813 else
814
815 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
816}
817
818/******************************************************************************
819 * FileMoniker_Enum
820 ******************************************************************************/
821HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
822{
823 TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
824
825 if (ppenumMoniker == NULL)
826 return E_POINTER;
827
828 *ppenumMoniker = NULL;
829
830 return S_OK;
831}
832
833/******************************************************************************
834 * FileMoniker_IsEqual
835 ******************************************************************************/
836HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
837{
838 ICOM_THIS(FileMonikerImpl,iface);
839 CLSID clsid;
840 LPOLESTR filePath;
841 IBindCtx* bind;
842 HRESULT res;
843
844 TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
845
846 if (pmkOtherMoniker==NULL)
847 return S_FALSE;
848
849 IMoniker_GetClassID(pmkOtherMoniker,&clsid);
850
851 if (!IsEqualCLSID(&clsid,&CLSID_FileMoniker))
852
853 return S_FALSE;
854
855 res=CreateBindCtx(0,&bind);
856 if (FAILED(res))
857 return res;
858
859 IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&filePath);
860
861 if (lstrcmpiW(filePath,
862 This->filePathName)!=0)
863
864 return S_FALSE;
865
866 return S_OK;
867}
868
869/******************************************************************************
870 * FileMoniker_Hash
871 ******************************************************************************/
872HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
873{
874 ICOM_THIS(FileMonikerImpl,iface);
875
876 int h = 0,i,skip,len;
877 int off = 0;
878 LPOLESTR val;
879
880 if (pdwHash==NULL)
881 return E_POINTER;
882
883 val = This->filePathName;
884 len = lstrlenW(val);
885
886 if (len < 16) {
887 for (i = len ; i > 0; i--) {
888 h = (h * 37) + val[off++];
889 }
890 } else {
891 /* only sample some characters */
892 skip = len / 8;
893 for (i = len ; i > 0; i -= skip, off += skip) {
894 h = (h * 39) + val[off];
895 }
896}
897
898 *pdwHash=h;
899
900 return S_OK;
901}
902
903/******************************************************************************
904 * FileMoniker_IsRunning
905 ******************************************************************************/
906HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,
907 IBindCtx* pbc,
908 IMoniker* pmkToLeft,
909 IMoniker* pmkNewlyRunning)
910{
911 IRunningObjectTable* rot;
912 HRESULT res;
913
914 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
915
916 if ( (pmkNewlyRunning!=NULL) && (IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK) )
917 return S_OK;
918
919 if (pbc==NULL)
920 return E_POINTER;
921
922 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
923
924 if (FAILED(res))
925 return res;
926
927 res = IRunningObjectTable_IsRunning(rot,iface);
928
929 IRunningObjectTable_Release(rot);
930
931 return res;
932}
933
934/******************************************************************************
935 * FileMoniker_GetTimeOfLastChange
936 ******************************************************************************/
937HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
938 IBindCtx* pbc,
939 IMoniker* pmkToLeft,
940 FILETIME* pFileTime)
941{
942 ICOM_THIS(FileMonikerImpl,iface);
943 IRunningObjectTable* rot;
944 HRESULT res;
945 WIN32_FILE_ATTRIBUTE_DATA info;
946
947 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pFileTime);
948
949 if (pFileTime==NULL)
950 return E_POINTER;
951
952 if (pmkToLeft!=NULL)
953 return E_INVALIDARG;
954
955 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
956
957 if (FAILED(res))
958 return res;
959
960 res= IRunningObjectTable_GetTimeOfLastChange(rot,iface,pFileTime);
961
962 if (FAILED(res)){ /* the moniker is not registred */
963
964 if (!GetFileAttributesExW(This->filePathName,GetFileExInfoStandard,&info))
965 return MK_E_NOOBJECT;
966
967 *pFileTime=info.ftLastWriteTime;
968}
969
970 return S_OK;
971}
972
973/******************************************************************************
974 * FileMoniker_Inverse
975 ******************************************************************************/
976HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
977{
978
979 TRACE("(%p,%p)\n",iface,ppmk);
980
981 return CreateAntiMoniker(ppmk);
982}
983
984/******************************************************************************
985 * FileMoniker_CommonPrefixWith
986 ******************************************************************************/
987HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
988{
989
990 LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath;
991 IBindCtx *pbind;
992 DWORD mkSys;
993 ULONG nb1,nb2,i,sameIdx;
994 BOOL machimeNameCase=FALSE;
995
996 if (ppmkPrefix==NULL)
997 return E_POINTER;
998
999 if (pmkOther==NULL)
1000 return E_INVALIDARG;
1001
1002 *ppmkPrefix=0;
1003
1004 /* check if we have the same type of moniker */
1005 IMoniker_IsSystemMoniker(pmkOther,&mkSys);
1006
1007 if(mkSys==MKSYS_FILEMONIKER){
1008
1009 CreateBindCtx(0,&pbind);
1010
1011 /* create a string based on common part of the two paths */
1012
1013 IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis);
1014 IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther);
1015
1016 nb1=FileMonikerImpl_DecomposePath(pathThis,&stringTable1);
1017 nb2=FileMonikerImpl_DecomposePath(pathOther,&stringTable2);
1018
1019 if (nb1==0 || nb2==0)
1020 return MK_E_NOPREFIX;
1021
1022 commonPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1));
1023
1024 *commonPath=0;
1025
1026 for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) &&
1027 (stringTable2[sameIdx]!=NULL) &&
1028 (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++);
1029
1030 if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){
1031
1032 machimeNameCase=TRUE;
1033
1034 for(i=2;i<sameIdx;i++)
1035
1036 if( (*stringTable1[i]=='\\') && (i+1 < sameIdx) && (*stringTable1[i+1]=='\\') ){
1037 machimeNameCase=FALSE;
1038 break;
1039}
1040 }
1041
1042 if (machimeNameCase && *stringTable1[sameIdx-1]=='\\')
1043 sameIdx--;
1044
1045 if (machimeNameCase && (sameIdx<=3) && (nb1 > 3 || nb2 > 3) )
1046 return MK_E_NOPREFIX;
1047
1048 for(i=0;i<sameIdx;i++)
1049 strcatW(commonPath,stringTable1[i]);
1050
1051 for(i=0;i<nb1;i++)
1052 CoTaskMemFree(stringTable1[i]);
1053
1054 CoTaskMemFree(stringTable1);
1055
1056 for(i=0;i<nb2;i++)
1057 CoTaskMemFree(stringTable2[i]);
1058
1059 CoTaskMemFree(stringTable2);
1060
1061 HeapFree(GetProcessHeap(),0,commonPath);
1062
1063 return CreateFileMoniker(commonPath,ppmkPrefix);
1064 }
1065 else
1066 return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
1067}
1068
1069/******************************************************************************
1070 * DecomposePath (local function)
1071 ******************************************************************************/
1072int WINAPI FileMonikerImpl_DecomposePath(LPOLESTR str, LPOLESTR** stringTable)
1073{
1074 WCHAR bSlash[] = {'\\',0};
1075 WCHAR word[MAX_PATH];
1076 int i=0,j,tabIndex=0;
1077 LPOLESTR *strgtable ;
1078
1079 int len=lstrlenW(str);
1080
1081 strgtable =CoTaskMemAlloc(len*sizeof(LPOLESTR));
1082
1083 if (strgtable==NULL)
1084 return E_OUTOFMEMORY;
1085
1086 while(str[i]!=0){
1087
1088 if(str[i]==bSlash[0]){
1089
1090 strgtable[tabIndex]=CoTaskMemAlloc(2*sizeof(WCHAR));
1091
1092 if (strgtable[tabIndex]==NULL)
1093 return E_OUTOFMEMORY;
1094
1095 strcpyW(strgtable[tabIndex++],bSlash);
1096
1097 i++;
1098
1099 }
1100 else {
1101
1102 for(j=0; str[i]!=0 && str[i]!=bSlash[0] ; i++,j++)
1103 word[j]=str[i];
1104
1105 word[j]=0;
1106
1107 strgtable[tabIndex]=CoTaskMemAlloc(sizeof(WCHAR)*(j+1));
1108
1109 if (strgtable[tabIndex]==NULL)
1110 return E_OUTOFMEMORY;
1111
1112 strcpyW(strgtable[tabIndex++],word);
1113 }
1114 }
1115 strgtable[tabIndex]=NULL;
1116
1117 *stringTable=strgtable;
1118
1119 return tabIndex;
1120}
1121
1122/******************************************************************************
1123 * FileMoniker_RelativePathTo
1124 ******************************************************************************/
1125HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
1126{
1127 IBindCtx *bind;
1128 HRESULT res;
1129 LPOLESTR str1=0,str2=0,*tabStr1=0,*tabStr2=0,relPath=0;
1130 DWORD len1=0,len2=0,sameIdx=0,j=0;
1131 WCHAR back[] ={'.','.','\\',0};
1132
1133 TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
1134
1135 if (ppmkRelPath==NULL)
1136 return E_POINTER;
1137
1138 if (pmOther==NULL)
1139 return E_INVALIDARG;
1140
1141 res=CreateBindCtx(0,&bind);
1142 if (FAILED(res))
1143 return res;
1144
1145 res=IMoniker_GetDisplayName(iface,bind,NULL,&str1);
1146 if (FAILED(res))
1147 return res;
1148 res=IMoniker_GetDisplayName(pmOther,bind,NULL,&str2);
1149 if (FAILED(res))
1150 return res;
1151
1152 len1=FileMonikerImpl_DecomposePath(str1,&tabStr1);
1153 len2=FileMonikerImpl_DecomposePath(str2,&tabStr2);
1154
1155 if (FAILED(len1) || FAILED(len2))
1156 return E_OUTOFMEMORY;
1157
1158 /* count the number of similar items from the begin of the two paths */
1159 for(sameIdx=0; ( (tabStr1[sameIdx]!=NULL) &&
1160 (tabStr2[sameIdx]!=NULL) &&
1161 (lstrcmpiW(tabStr1[sameIdx],tabStr2[sameIdx])==0)); sameIdx++);
1162
1163 /* begin the construction of relativePath */
1164 /* if the two paths have a consecutive similar item from the begin ! the relativePath will be composed */
1165 /* by "..\\" in the begin */
1166 relPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(1+lstrlenW(str1)+lstrlenW(str2)));
1167
1168 *relPath=0;
1169
1170 if (len2>0 && !(len1==1 && len2==1 && sameIdx==0))
1171 for(j=sameIdx;(tabStr1[j] != NULL); j++)
1172 if (*tabStr1[j]!='\\')
1173 strcatW(relPath,back);
1174
1175 /* add items of the second path (similar items with the first path are not included) to the relativePath */
1176 for(j=sameIdx;tabStr2[j]!=NULL;j++)
1177 strcatW(relPath,tabStr2[j]);
1178
1179 res=CreateFileMoniker(relPath,ppmkRelPath);
1180
1181 for(j=0; tabStr1[j]!=NULL;j++)
1182 CoTaskMemFree(tabStr1[j]);
1183 for(j=0; tabStr2[j]!=NULL;j++)
1184 CoTaskMemFree(tabStr2[j]);
1185 CoTaskMemFree(tabStr1);
1186 CoTaskMemFree(tabStr2);
1187 CoTaskMemFree(str1);
1188 CoTaskMemFree(str2);
1189 HeapFree(GetProcessHeap(),0,relPath);
1190
1191 if (len1==0 || len2==0 || (len1==1 && len2==1 && sameIdx==0))
1192 return MK_S_HIM;
1193
1194 return res;
1195}
1196
1197/******************************************************************************
1198 * FileMoniker_GetDisplayName
1199 ******************************************************************************/
1200HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,
1201 IBindCtx* pbc,
1202 IMoniker* pmkToLeft,
1203 LPOLESTR *ppszDisplayName)
1204{
1205 ICOM_THIS(FileMonikerImpl,iface);
1206
1207 int len=lstrlenW(This->filePathName);
1208
1209 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
1210
1211 if (ppszDisplayName==NULL)
1212 return E_POINTER;
1213
1214 if (pmkToLeft!=NULL)
1215 return E_INVALIDARG;
1216
1217 *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
1218 if (*ppszDisplayName==NULL)
1219 return E_OUTOFMEMORY;
1220
1221 strcpyW(*ppszDisplayName,This->filePathName);
1222
1223 return S_OK;
1224}
1225
1226/******************************************************************************
1227 * FileMoniker_ParseDisplayName
1228 ******************************************************************************/
1229HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,
1230 IBindCtx* pbc,
1231 IMoniker* pmkToLeft,
1232 LPOLESTR pszDisplayName,
1233 ULONG* pchEaten,
1234 IMoniker** ppmkOut)
1235{
1236 FIXME("(%p,%p,%p,%p,%p,%p),stub!\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
1237 return E_NOTIMPL;
1238}
1239
1240/******************************************************************************
1241 * FileMoniker_IsSystemMoniker
1242 ******************************************************************************/
1243HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
1244{
1245 TRACE("(%p,%p)\n",iface,pwdMksys);
1246
1247 if (!pwdMksys)
1248 return E_POINTER;
1249
1250 (*pwdMksys)=MKSYS_FILEMONIKER;
1251
1252 return S_OK;
1253}
1254
1255/*******************************************************************************
1256 * FileMonikerIROTData_QueryInterface
1257 *******************************************************************************/
1258HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
1259{
1260
1261 ICOM_THIS_From_IROTData(IMoniker, iface);
1262
1263 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
1264
1265 return FileMonikerImpl_QueryInterface(This, riid, ppvObject);
1266}
1267
1268/***********************************************************************
1269 * FileMonikerIROTData_AddRef
1270 */
1271ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData *iface)
1272{
1273 ICOM_THIS_From_IROTData(IMoniker, iface);
1274
1275 TRACE("(%p)\n",This);
1276
1277 return FileMonikerImpl_AddRef(This);
1278}
1279
1280/***********************************************************************
1281 * FileMonikerIROTData_Release
1282 */
1283ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface)
1284{
1285 ICOM_THIS_From_IROTData(IMoniker, iface);
1286
1287 TRACE("(%p)\n",This);
1288
1289 return FileMonikerImpl_Release(This);
1290}
1291
1292/******************************************************************************
1293 * FileMonikerIROTData_GetComparaisonData
1294 ******************************************************************************/
1295HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
1296 BYTE* pbData,
1297 ULONG cbMax,
1298 ULONG* pcbData)
1299{
1300 FIXME("(),stub!\n");
1301 return E_NOTIMPL;
1302}
1303
1304/******************************************************************************
1305 * CreateFileMoniker16
1306 ******************************************************************************/
1307HRESULT WINAPI CreateFileMoniker16(LPCOLESTR16 lpszPathName,LPMONIKER* ppmk)
1308{
1309
1310 FIXME("(%s,%p),stub!\n",lpszPathName,ppmk);
1311 return E_NOTIMPL;
1312}
1313
1314/******************************************************************************
1315 * CreateFileMoniker
1316 ******************************************************************************/
1317HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk)
1318{
1319 FileMonikerImpl* newFileMoniker = 0;
1320 HRESULT hr = E_FAIL;
1321 IID riid=IID_IMoniker;
1322
1323 TRACE("(%p,%p)\n",lpszPathName,ppmk);
1324
1325 if (ppmk==NULL)
1326 return E_POINTER;
1327
1328 if(lpszPathName==NULL)
1329 return MK_E_SYNTAX;
1330
1331 *ppmk=0;
1332
1333 newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl));
1334
1335 if (newFileMoniker == 0)
1336 return E_OUTOFMEMORY;
1337
1338 hr = FileMonikerImpl_Construct(newFileMoniker,lpszPathName);
1339
1340 if (SUCCEEDED(hr))
1341 hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&riid,(void**)ppmk);
1342 else
1343 HeapFree(GetProcessHeap(),0,newFileMoniker);
1344
1345 return hr;
1346}
Note: See TracBrowser for help on using the repository browser.