source: trunk/src/ole32/old/filemoniker.cpp@ 6496

Last change on this file since 6496 was 5601, checked in by sandervl, 24 years ago

created

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