source: trunk/src/ole32/filemoniker.cpp@ 3831

Last change on this file since 3831 was 3167, checked in by davidr, 25 years ago

Ported changes from wine/corel sources

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