| /* |
| * Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL) |
| * |
| * Copyright 1997 Marcus Meissner |
| * Copyright 1998 Juergen Schmied |
| * |
| * !!! currently work in progress on all classes !!! |
| * <contact juergen.schmied@metronet.de, 980801> |
| */ |
| |
| #include <ctype.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include "ole.h" |
| #include "ole2.h" |
| #include "debug.h" |
| #include "compobj.h" |
| #include "interfaces.h" |
| #include "shlobj.h" |
| #include "winerror.h" |
| #include "winnls.h" |
| #include "winproc.h" |
| |
| /* FIXME should be moved to a header file. IsEqualGUID |
| is declared but not exported in compobj.c !!!*/ |
| #define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID))) |
| #define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) |
| #define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) |
| /*************************************************************************** |
| * GetNextElement (internal function) |
| * |
| * gets a part of a string till the first backslash |
| * |
| * PARAMETERS |
| * pszNext [IN] string to get the element from |
| * pszOut [IN] pointer to buffer whitch receives string |
| * dwOut [IN] length of pszOut |
| * |
| * RETURNS |
| * LPSTR pointer to first, not yet parsed char |
| */ |
| LPSTR GetNextElement(LPSTR pszNext,LPSTR pszOut,DWORD dwOut) |
| { LPSTR pszTail = pszNext; |
| DWORD dwCopy; |
| TRACE(shell,"(%s %p 0x%08lx)\n",debugstr_a(pszNext),pszOut,dwOut); |
| |
| if(!pszNext || !*pszNext) |
| return NULL; |
| |
| while(*pszTail && (*pszTail != '\\')) |
| { pszTail++; |
| } |
| dwCopy=((LPBYTE)pszTail-(LPBYTE)pszNext)/sizeof(CHAR)+1; |
| lstrcpyn32A(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy); |
| |
| if(*pszTail) |
| { pszTail++; |
| } |
| |
| TRACE(shell,"--(%s %s 0x%08lx)\n",debugstr_a(pszNext),debugstr_a(pszOut),dwOut); |
| return pszTail; |
| } |
| |
| /************************************************************************** |
| * IClassFactory Implementation |
| */ |
| static HRESULT WINAPI IClassFactory_QueryInterface(LPCLASSFACTORY,REFIID,LPVOID*); |
| static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY); |
| static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY); |
| static HRESULT WINAPI IClassFactory_CreateInstance(); |
| static HRESULT WINAPI IClassFactory_LockServer(); |
| /************************************************************************** |
| * IClassFactory_VTable |
| */ |
| static IClassFactory_VTable clfvt = |
| { IClassFactory_QueryInterface, |
| IClassFactory_AddRef, |
| IClassFactory_Release, |
| IClassFactory_CreateInstance, |
| IClassFactory_LockServer |
| }; |
| |
| /************************************************************************** |
| * IClassFactory_Constructor |
| */ |
| |
| LPCLASSFACTORY IClassFactory_Constructor() |
| { LPCLASSFACTORY lpclf; |
| |
| lpclf= (LPCLASSFACTORY)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactory)); |
| lpclf->ref = 1; |
| lpclf->lpvtbl = &clfvt; |
| TRACE(shell,"(%p)->()\n",lpclf); |
| return lpclf; |
| } |
| /************************************************************************** |
| * IClassFactory::QueryInterface |
| */ |
| static HRESULT WINAPI IClassFactory_QueryInterface( |
| LPCLASSFACTORY this, REFIID riid, LPVOID *ppvObj) |
| { char xriid[50]; |
| WINE_StringFromCLSID((LPCLSID)riid,xriid); |
| TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid); |
| |
| *ppvObj = NULL; |
| |
| if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ |
| { *ppvObj = this; |
| } |
| else if(IsEqualIID(riid, &IID_IClassFactory)) /*IClassFactory*/ |
| { *ppvObj = (IClassFactory*)this; |
| } |
| |
| if(*ppvObj) |
| { (*(LPCLASSFACTORY*)ppvObj)->lpvtbl->fnAddRef(this); |
| TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); |
| return S_OK; |
| } |
| TRACE(shell,"-- Interface: E_NOINTERFACE\n"); |
| return E_NOINTERFACE; |
| } |
| /****************************************************************************** |
| * IClassFactory_AddRef |
| */ |
| static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY this) |
| { TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); |
| return ++(this->ref); |
| } |
| /****************************************************************************** |
| * IClassFactory_Release |
| */ |
| static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY this) |
| { TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); |
| if (!--(this->ref)) |
| { TRACE(shell,"-- destroying IClassFactory(%p)\n",this); |
| HeapFree(GetProcessHeap(),0,this); |
| return 0; |
| } |
| return this->ref; |
| } |
| /****************************************************************************** |
| * IClassFactory_CreateInstance |
| */ |
| static HRESULT WINAPI IClassFactory_CreateInstance( |
| LPCLASSFACTORY this, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject) |
| { IUnknown *pObj = NULL; |
| HRESULT hres; |
| char xriid[50]; |
| |
| WINE_StringFromCLSID((LPCLSID)riid,xriid); |
| TRACE(shell,"%p->(%p,\n\tIID:\t%s,%p)\n",this,pUnknown,xriid,ppObject); |
| |
| *ppObject = NULL; |
| |
| if(pUnknown) |
| { return(CLASS_E_NOAGGREGATION); |
| } |
| |
| if (IsEqualIID(riid, &IID_IShellFolder)) |
| { pObj = (IUnknown *)IShellFolder_Constructor(NULL,NULL); |
| } |
| else if (IsEqualIID(riid, &IID_IShellView)) |
| { pObj = (IUnknown *)IShellView_Constructor(); |
| } |
| else if (IsEqualIID(riid, &IID_IShellLink)) |
| { pObj = (IUnknown *)IShellLink_Constructor(); |
| } |
| else |
| { ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid); |
| return(E_NOINTERFACE); |
| } |
| |
| if (!pObj) |
| { return(E_OUTOFMEMORY); |
| } |
| |
| hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject); |
| pObj->lpvtbl->fnRelease(pObj); |
| TRACE(shell,"-- Object created: (%p)->%p\n",this,*ppObject); |
| |
| return hres; |
| } |
| /****************************************************************************** |
| * IClassFactory_LockServer |
| */ |
| static HRESULT WINAPI IClassFactory_LockServer(LPCLASSFACTORY this, BOOL32 fLock) |
| { TRACE(shell,"%p->(0x%x), not implemented\n",this, fLock); |
| return E_NOTIMPL; |
| } |
| |
| /************************************************************************** |
| * IEnumIDList Implementation |
| */ |
| static HRESULT WINAPI IEnumIDList_QueryInterface(LPENUMIDLIST,REFIID,LPVOID*); |
| static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST); |
| static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST); |
| static HRESULT WINAPI IEnumIDList_Next(LPENUMIDLIST,ULONG,LPITEMIDLIST*,ULONG*); |
| static HRESULT WINAPI IEnumIDList_Skip(LPENUMIDLIST,ULONG); |
| static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST); |
| static HRESULT WINAPI IEnumIDList_Clone(LPENUMIDLIST,LPENUMIDLIST*); |
| static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST,LPCSTR, DWORD); |
| static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST,LPITEMIDLIST); |
| static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST); |
| /************************************************************************** |
| * IEnumIDList_VTable |
| */ |
| static IEnumIDList_VTable eidlvt = |
| { IEnumIDList_QueryInterface, |
| IEnumIDList_AddRef, |
| IEnumIDList_Release, |
| IEnumIDList_Next, |
| IEnumIDList_Skip, |
| IEnumIDList_Reset, |
| IEnumIDList_Clone, |
| IEnumIDList_CreateEnumList, |
| IEnumIDList_AddToEnumList, |
| IEnumIDList_DeleteList |
| }; |
| |
| /************************************************************************** |
| * IEnumIDList_Constructor |
| */ |
| |
| LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags, HRESULT* pResult) |
| { LPENUMIDLIST lpeidl; |
| |
| lpeidl = (LPENUMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDList)); |
| lpeidl->ref = 1; |
| lpeidl->lpvtbl = &eidlvt; |
| lpeidl->mpFirst=NULL; |
| lpeidl->mpLast=NULL; |
| lpeidl->mpCurrent=NULL; |
| |
| TRACE(shell,"(%p)->(%s 0x%08lx %p)\n",lpeidl,debugstr_a(lpszPath),dwFlags,pResult); |
| |
| lpeidl->mpPidlMgr=PidlMgr_Constructor(); |
| if (!lpeidl->mpPidlMgr) |
| { if (pResult) |
| { *pResult=E_OUTOFMEMORY; |
| HeapFree(GetProcessHeap(),0,lpeidl); |
| return NULL; |
| } |
| } |
| |
| if(!IEnumIDList_CreateEnumList(lpeidl, lpszPath, dwFlags)) |
| { if(pResult) |
| { *pResult = E_OUTOFMEMORY; |
| HeapFree(GetProcessHeap(),0,lpeidl->mpPidlMgr); |
| HeapFree(GetProcessHeap(),0,lpeidl); |
| return NULL; |
| } |
| } |
| |
| TRACE(shell,"-- (%p)->()\n",lpeidl); |
| return lpeidl; |
| } |
| |
| /************************************************************************** |
| * EnumIDList::QueryInterface |
| */ |
| static HRESULT WINAPI IEnumIDList_QueryInterface( |
| LPENUMIDLIST this, REFIID riid, LPVOID *ppvObj) |
| { char xriid[50]; |
| WINE_StringFromCLSID((LPCLSID)riid,xriid); |
| TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); |
| |
| *ppvObj = NULL; |
| |
| if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ |
| { *ppvObj = this; |
| } |
| else if(IsEqualIID(riid, &IID_IEnumIDList)) /*IEnumIDList*/ |
| { *ppvObj = (IEnumIDList*)this; |
| } |
| |
| if(*ppvObj) |
| { (*(LPENUMIDLIST*)ppvObj)->lpvtbl->fnAddRef(this); |
| TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); |
| return S_OK; |
| } |
| TRACE(shell,"-- Interface: E_NOINTERFACE\n"); |
| return E_NOINTERFACE; |
| } |
| |
| /****************************************************************************** |
| * IEnumIDList_AddRef |
| */ |
| static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST this) |
| { TRACE(shell,"(%p)->()\n",this); |
| return ++(this->ref); |
| } |
| /****************************************************************************** |
| * IEnumIDList_Release |
| */ |
| static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST this) |
| { TRACE(shell,"(%p)->()\n",this); |
| if (!--(this->ref)) |
| { TRACE(shell," destroying IEnumIDList(%p)\n",this); |
| HeapFree(GetProcessHeap(),0,this); |
| return 0; |
| } |
| return this->ref; |
| } |
| |
| /************************************************************************** |
| * IEnumIDList_Next |
| */ |
| |
| static HRESULT WINAPI IEnumIDList_Next( |
| LPENUMIDLIST this,ULONG celt,LPITEMIDLIST * rgelt,ULONG *pceltFetched) |
| { ULONG i; |
| HRESULT hr = S_OK; |
| LPITEMIDLIST temp; |
| |
| TRACE(shell,"(%p)->(%ld,%p, %p)\n",this,celt,rgelt,pceltFetched); |
| |
| /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's |
| subsystems actually use it (and so may a third party browser) |
| */ |
| if(pceltFetched) |
| *pceltFetched = 0; |
| |
| *rgelt=0; |
| |
| if(celt > 1 && !pceltFetched) |
| { return E_INVALIDARG; |
| } |
| |
| for(i = 0; i < celt; i++) |
| { if(!(this->mpCurrent)) |
| { hr = S_FALSE; |
| break; |
| } |
| temp = ILClone(this->mpCurrent->pidl); |
| rgelt[i] = temp; |
| this->mpCurrent = this->mpCurrent->pNext; |
| } |
| if(pceltFetched) |
| { *pceltFetched = i; |
| } |
| |
| return hr; |
| } |
| |
| /************************************************************************** |
| * IEnumIDList_Skip |
| */ |
| static HRESULT WINAPI IEnumIDList_Skip( |
| LPENUMIDLIST this,ULONG celt) |
| { DWORD dwIndex; |
| HRESULT hr = S_OK; |
| |
| TRACE(shell,"(%p)->(%lu)\n",this,celt); |
| |
| for(dwIndex = 0; dwIndex < celt; dwIndex++) |
| { if(!this->mpCurrent) |
| { hr = S_FALSE; |
| break; |
| } |
| this->mpCurrent = this->mpCurrent->pNext; |
| } |
| return hr; |
| } |
| /************************************************************************** |
| * IEnumIDList_Reset |
| */ |
| static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST this) |
| { TRACE(shell,"(%p)\n",this); |
| this->mpCurrent = this->mpFirst; |
| return S_OK; |
| } |
| /************************************************************************** |
| * IEnumIDList_Clone |
| */ |
| static HRESULT WINAPI IEnumIDList_Clone( |
| LPENUMIDLIST this,LPENUMIDLIST * ppenum) |
| { TRACE(shell,"(%p)->() to (%p)->() E_NOTIMPL\n",this,ppenum); |
| return E_NOTIMPL; |
| } |
| /************************************************************************** |
| * EnumIDList_CreateEnumList() |
| * fixme: devices not handled |
| * fixme: add wildcards to path |
| */ |
| static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST this, LPCSTR lpszPath, DWORD dwFlags) |
| { LPITEMIDLIST pidl=NULL; |
| WIN32_FIND_DATA32A stffile; |
| HANDLE32 hFile; |
| DWORD dwDrivemap; |
| CHAR szDriveName[4]; |
| CHAR szPath[MAX_PATH]; |
| |
| TRACE(shell,"(%p)->(%s 0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags); |
| |
| if (lpszPath && lpszPath[0]!='\0') |
| { strcpy(szPath, lpszPath); |
| PathAddBackslash(szPath); |
| strcat(szPath,"*.*"); |
| } |
| |
| /*enumerate the folders*/ |
| if(dwFlags & SHCONTF_FOLDERS) |
| { /* special case - we can't enumerate the Desktop level Objects (MyComputer,Nethood... |
| so we need to fake an enumeration of those.*/ |
| if(!lpszPath) |
| { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (special) items\n",this); |
| //create the pidl for this item |
| pidl = this->mpPidlMgr->lpvtbl->fnCreateMyComputer(this->mpPidlMgr); |
| if(pidl) |
| { if(!IEnumIDList_AddToEnumList(this, pidl)) |
| return FALSE; |
| } |
| } |
| else if (lpszPath[0]=='\0') /* enumerate the drives*/ |
| { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (drives)\n",this); |
| dwDrivemap = GetLogicalDrives(); |
| strcpy (szDriveName,"A:\\"); |
| while (szDriveName[0]<='Z') |
| { if(dwDrivemap & 0x00000001L) |
| { pidl = this->mpPidlMgr->lpvtbl->fnCreateDrive(this->mpPidlMgr,szDriveName ); |
| if(pidl) |
| { if(!IEnumIDList_AddToEnumList(this, pidl)) |
| return FALSE; |
| } |
| } |
| szDriveName[0]++; |
| dwDrivemap = dwDrivemap >> 1; |
| } |
| } |
| |
| else |
| { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS of %s\n",this,debugstr_a(szPath)); |
| hFile = FindFirstFile32A(szPath,&stffile); |
| if ( hFile != INVALID_HANDLE_VALUE32 ) |
| { do |
| { if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, "..")) |
| { pidl = this->mpPidlMgr->lpvtbl->fnCreateFolder(this->mpPidlMgr, stffile.cFileName); |
| if(pidl) |
| { if(!IEnumIDList_AddToEnumList(this, pidl)) |
| { return FALSE; |
| } |
| } |
| else |
| { return FALSE; |
| } |
| } |
| } while( FindNextFile32A(hFile,&stffile)); |
| FindClose32 (hFile); |
| } |
| } |
| } |
| //enumerate the non-folder items (values) |
| if(dwFlags & SHCONTF_NONFOLDERS) |
| { if(lpszPath) |
| { TRACE (shell,"-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",this,debugstr_a(szPath)); |
| hFile = FindFirstFile32A(szPath,&stffile); |
| if ( hFile != INVALID_HANDLE_VALUE32 ) |
| { do |
| { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) |
| { pidl = this->mpPidlMgr->lpvtbl->fnCreateValue(this->mpPidlMgr, stffile.cFileName); |
| if(pidl) |
| { if(!IEnumIDList_AddToEnumList(this, pidl)) |
| { return FALSE; |
| } |
| } |
| else |
| { return FALSE; |
| } |
| } |
| } while( FindNextFile32A(hFile,&stffile)); |
| FindClose32 (hFile); |
| } |
| } |
| } |
| return TRUE; |
| } |
| |
| /************************************************************************** |
| * EnumIDList_AddToEnumList() |
| */ |
| static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST this,LPITEMIDLIST pidl) |
| { LPENUMLIST pNew; |
| |
| TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); |
| pNew = (LPENUMLIST)HeapAlloc(GetProcessHeap(),0,sizeof(ENUMLIST)); |
| if(pNew) |
| { //set the next pointer |
| pNew->pNext = NULL; |
| pNew->pidl = pidl; |
| |
| //is this the first item in the list? |
| if(!this->mpFirst) |
| { this->mpFirst = pNew; |
| this->mpCurrent = pNew; |
| } |
| |
| if(this->mpLast) |
| { //add the new item to the end of the list |
| this->mpLast->pNext = pNew; |
| } |
| |
| //update the last item pointer |
| this->mpLast = pNew; |
| TRACE(shell,"-- (%p)->(first=%p, last=%p)\n",this,this->mpFirst,this->mpLast); |
| return TRUE; |
| } |
| return FALSE; |
| } |
| /************************************************************************** |
| * EnumIDList_DeleteList() |
| */ |
| static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST this) |
| { LPENUMLIST pDelete; |
| |
| TRACE(shell,"(%p)->()\n",this); |
| |
| while(this->mpFirst) |
| { pDelete = this->mpFirst; |
| this->mpFirst = pDelete->pNext; |
| SHFree(pDelete->pidl); |
| SHFree(pDelete); |
| } |
| this->mpFirst = this->mpLast = this->mpCurrent = NULL; |
| return TRUE; |
| } |
| /*********************************************************************** |
| * IShellView implementation |
| */ |
| static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW,REFIID riid, LPVOID *ppvObj); |
| static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW) ; |
| static ULONG WINAPI IShellView_Release(LPSHELLVIEW); |
| |
| // *** IOleWindow methods *** |
| static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW,HWND32 * lphwnd); |
| static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW,BOOL32 fEnterMode); |
| |
| // *** IShellView methods *** |
| static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW,LPMSG32 lpmsg); |
| static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW,BOOL32 fEnable); |
| static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW,UINT32 uState); |
| static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW); |
| static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW, IShellView *lpPrevView,LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32 *phWnd); |
| static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW); |
| static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW, LPFOLDERSETTINGS lpfs); |
| static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam); |
| static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW); |
| static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT32 uFlags); |
| static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT32 uItem, REFIID riid,LPVOID *ppv); |
| |
| static struct IShellView_VTable svvt = |
| { IShellView_QueryInterface, |
| IShellView_AddRef, |
| IShellView_Release, |
| IShellView_GetWindow, |
| IShellView_ContextSensitiveHelp, |
| IShellView_TranslateAccelerator, |
| IShellView_EnableModeless, |
| IShellView_UIActivate, |
| IShellView_Refresh, |
| IShellView_CreateViewWindow, |
| IShellView_DestroyViewWindow, |
| IShellView_GetCurrentInfo, |
| IShellView_AddPropertySheetPages, |
| IShellView_SaveViewState, |
| IShellView_SelectItem, |
| IShellView_GetItemObject |
| }; |
| /************************************************************************** |
| * IShellView_Constructor |
| */ |
| LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER pFolder, LPCITEMIDLIST pidl) |
| { LPSHELLVIEW sv; |
| sv=(LPSHELLVIEW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellView)); |
| sv->ref=1; |
| sv->lpvtbl=&svvt; |
| |
| sv->mpidl = ILClone(pidl); |
| |
| sv->pSFParent = pFolder; |
| if(sv->pSFParent) |
| sv->pSFParent->lpvtbl->fnAddRef(sv->pSFParent); |
| |
| TRACE(shell,"(%p)->(%p pidl=%p)\n",sv, pFolder, pidl); |
| return sv; |
| } |
| /************************************************************************** |
| * ShellView_WndProc |
| */ |
| LRESULT CALLBACK ShellView_WndProc(HWND32 hWnd, UINT32 uMessage, WPARAM32 wParam, LPARAM lParam) |
| { LPSHELLVIEW pThis = (LPSHELLVIEW)GetWindowLong32A(hWnd, GWL_USERDATA); |
| LPCREATESTRUCT32A lpcs; |
| |
| FIXME(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam); |
| |
| switch (uMessage) |
| { case WM_NCCREATE: |
| { TRACE(shell,"WM_NCCREATE\n"); |
| lpcs = (LPCREATESTRUCT32A)lParam; |
| pThis = (LPSHELLVIEW)(lpcs->lpCreateParams); |
| SetWindowLong32A(hWnd, GWL_USERDATA, (LONG)pThis); |
| |
| //set the window handle |
| pThis->hWnd = hWnd; |
| } |
| break; |
| |
| case WM_SIZE: |
| TRACE(shell,"WM_SIZE\n"); |
| return FALSE; |
| |
| case WM_CREATE: |
| TRACE(shell,"WM_CREATE\n"); |
| return FALSE; |
| |
| case WM_SETFOCUS: |
| TRACE(shell,"WM_SETFOCUS\n"); |
| return FALSE; |
| |
| case WM_KILLFOCUS: |
| TRACE(shell,"WM_KILLFOCUS\n"); |
| return FALSE; |
| |
| case WM_ACTIVATE: |
| TRACE(shell,"WM_ACTIVATE\n"); |
| return FALSE; |
| |
| case WM_COMMAND: |
| TRACE(shell,"WM_COMMAND\n"); |
| return FALSE; |
| |
| case WM_INITMENUPOPUP: |
| TRACE(shell,"WM_INITMENUPOPUP\n"); |
| return FALSE; |
| |
| case WM_NOTIFY: |
| TRACE(shell,"WM_NOTIFY\n"); |
| return FALSE; |
| |
| /* case WM_SETTINGCHANGE: |
| return FALSE;*/ |
| } |
| |
| return DefWindowProc32A (hWnd, uMessage, wParam, lParam); |
| } |
| |
| |
| /************************************************************************** |
| * IShellView::QueryInterface |
| */ |
| static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW this,REFIID riid, LPVOID *ppvObj) |
| { char xriid[50]; |
| WINE_StringFromCLSID((LPCLSID)riid,xriid); |
| TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); |
| |
| *ppvObj = NULL; |
| |
| if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ |
| { *ppvObj = this; |
| } |
| else if(IsEqualIID(riid, &IID_IShellView)) /*IShellView*/ |
| { *ppvObj = (IShellView*)this; |
| } |
| |
| if(*ppvObj) |
| { (*(LPSHELLVIEW*)ppvObj)->lpvtbl->fnAddRef(this); |
| TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); |
| return S_OK; |
| } |
| TRACE(shell,"-- Interface: E_NOINTERFACE\n"); |
| return E_NOINTERFACE; |
| } |
| /************************************************************************** |
| * IShellView::AddRef |
| */ |
| static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW this) |
| { TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1); |
| return ++(this->ref); |
| } |
| /************************************************************************** |
| * IShellView::Release |
| */ |
| static ULONG WINAPI IShellView_Release(LPSHELLVIEW this) |
| { TRACE(shell,"(%p)->()\n",this); |
| if (!--(this->ref)) |
| { TRACE(shell," destroying IEnumIDList(%p)\n",this); |
| |
| if(this->pSFParent) |
| this->pSFParent->lpvtbl->fnRelease(this->pSFParent); |
| |
| HeapFree(GetProcessHeap(),0,this); |
| return 0; |
| } |
| return this->ref; |
| } |
| /************************************************************************** |
| * IShellView::GetWindow |
| */ |
| static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND32 * phWnd) |
| { TRACE(shell,"(%p) stub\n",this); |
| *phWnd = this->hWnd; |
| |
| return S_OK; |
| } |
| static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL32 fEnterMode) |
| { FIXME(shell,"(%p) stub\n",this); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW this,LPMSG32 lpmsg) |
| { FIXME(shell,"(%p)->(%p) stub\n",this,lpmsg); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW this,BOOL32 fEnable) |
| { FIXME(shell,"(%p) stub\n",this); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW this,UINT32 uState) |
| { FIXME(shell,"(%p) stub\n",this); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW this) |
| { FIXME(shell,"(%p) stub\n",this); |
| return S_OK; |
| } |
| static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW this, IShellView *lpPrevView, |
| LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32 *phWnd) |
| { WNDCLASS32A wc; |
| *phWnd = 0; |
| |
| TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd); |
| |
| //if our window class has not been registered, then do so |
| if(!GetClassInfo32A(shell32_hInstance, SV_CLASS_NAME, &wc)) |
| { ZeroMemory(&wc, sizeof(wc)); |
| wc.style = CS_HREDRAW | CS_VREDRAW; |
| wc.lpfnWndProc = (WNDPROC32) ShellView_WndProc; |
| wc.cbClsExtra = 0; |
| wc.cbWndExtra = 0; |
| wc.hInstance = shell32_hInstance; |
| wc.hIcon = 0; |
| wc.hCursor = LoadCursor32A (0, IDC_ARROW32A); |
| wc.hbrBackground = (HBRUSH32)(COLOR_WINDOW + 1); |
| wc.lpszMenuName = NULL; |
| wc.lpszClassName = SV_CLASS_NAME; |
| |
| if(!RegisterClass32A(&wc)) |
| return E_FAIL; |
| } |
| //set up the member variables |
| this->pShellBrowser = psb; |
| this->FolderSettings = *lpfs; |
| |
| //get our parent window |
| this->pShellBrowser->lpvtbl->fnGetWindow(this->pShellBrowser, &(this->hWndParent)); |
| |
| *phWnd = CreateWindowEx32A(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, |
| prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top, |
| this->hWndParent, 0, shell32_hInstance, (LPVOID)this); |
| |
| if(!*phWnd) |
| return E_FAIL; |
| |
| this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser); |
| |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this) |
| { FIXME(shell,"(%p) stub\n",this); |
| |
| this->pShellBrowser->lpvtbl->fnRelease(this->pShellBrowser); |
| |
| return S_OK; |
| } |
| static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW this, LPFOLDERSETTINGS lpfs) |
| { FIXME(shell,"(%p)->(%p)stub\n",this, lpfs); |
| |
| *lpfs = this->FolderSettings; |
| return S_OK; |
| } |
| static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam) |
| { FIXME(shell,"(%p) stub\n",this); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW this) |
| { FIXME(shell,"(%p) stub\n",this); |
| return S_OK; |
| } |
| static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW this, LPCITEMIDLIST pidlItem, UINT32 uFlags) |
| { FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",this, pidlItem, uFlags); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT32 uItem, REFIID riid,LPVOID *ppvOut) |
| { char xriid[50]; |
| WINE_StringFromCLSID((LPCLSID)riid,xriid); |
| |
| FIXME(shell,"(%p)->(0x%08x,\n\t%s, %p)stub\n",this, uItem, xriid, ppvOut); |
| |
| *ppvOut = NULL; |
| return E_NOTIMPL; |
| } |
| |
| /*********************************************************************** |
| * IShellFolder implementation |
| */ |
| static HRESULT WINAPI IShellFolder_QueryInterface(LPSHELLFOLDER,REFIID,LPVOID*); |
| static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER); |
| static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER); |
| static HRESULT WINAPI IShellFolder_Initialize(LPSHELLFOLDER,LPCITEMIDLIST); |
| static HRESULT WINAPI IShellFolder_ParseDisplayName(LPSHELLFOLDER,HWND32,LPBC,LPOLESTR32,DWORD*,LPITEMIDLIST*,DWORD*); |
| static HRESULT WINAPI IShellFolder_EnumObjects(LPSHELLFOLDER,HWND32,DWORD,LPENUMIDLIST*); |
| static HRESULT WINAPI IShellFolder_BindToObject(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*); |
| static HRESULT WINAPI IShellFolder_BindToStorage(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*); |
| static HRESULT WINAPI IShellFolder_CompareIDs(LPSHELLFOLDER,LPARAM,LPCITEMIDLIST,LPCITEMIDLIST); |
| static HRESULT WINAPI IShellFolder_CreateViewObject(LPSHELLFOLDER,HWND32,REFIID,LPVOID*); |
| static HRESULT WINAPI IShellFolder_GetAttributesOf(LPSHELLFOLDER,UINT32,LPCITEMIDLIST*,DWORD*); |
| static HRESULT WINAPI IShellFolder_GetUIObjectOf(LPSHELLFOLDER,HWND32,UINT32,LPCITEMIDLIST*,REFIID,UINT32*,LPVOID*); |
| static HRESULT WINAPI IShellFolder_GetDisplayNameOf(LPSHELLFOLDER,LPCITEMIDLIST,DWORD,LPSTRRET); |
| static HRESULT WINAPI IShellFolder_SetNameOf(LPSHELLFOLDER,HWND32,LPCITEMIDLIST,LPCOLESTR32,DWORD,LPITEMIDLIST*); |
| /*********************************************************************** |
| * |
| * IShellFolder_VTable |
| */ |
| static struct IShellFolder_VTable sfvt = |
| { IShellFolder_QueryInterface, |
| IShellFolder_AddRef, |
| IShellFolder_Release, |
| IShellFolder_ParseDisplayName, |
| IShellFolder_EnumObjects, |
| IShellFolder_BindToObject, |
| IShellFolder_BindToStorage, |
| IShellFolder_CompareIDs, |
| IShellFolder_CreateViewObject, |
| IShellFolder_GetAttributesOf, |
| IShellFolder_GetUIObjectOf, |
| IShellFolder_GetDisplayNameOf, |
| IShellFolder_SetNameOf |
| /* IShellFolder_Initialize*/ |
| }; |
| /************************************************************************** |
| * IShellFolder_Constructor |
| */ |
| |
| LPSHELLFOLDER IShellFolder_Constructor(LPSHELLFOLDER pParent,LPITEMIDLIST pidl) |
| { LPSHELLFOLDER sf; |
| DWORD dwSize=0; |
| sf=(LPSHELLFOLDER)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder)); |
| sf->ref=1; |
| sf->lpvtbl=&sfvt; |
| sf->mlpszFolder=NULL; |
| sf->mpSFParent=pParent; |
| |
| TRACE(shell,"(%p)->(parent=%p, pidl=%p)\n",sf,pParent, pidl); |
| |
| /* create own pidl-manager*/ |
| sf->pPidlMgr = PidlMgr_Constructor(); |
| if (! sf->pPidlMgr ) |
| { HeapFree(GetProcessHeap(),0,sf); |
| ERR (shell,"-- Could not initialize PidMGR\n"); |
| return NULL; |
| } |
| |
| /* keep a copy of the pidl in the instance*/ |
| sf->mpidl = ILClone(pidl); |
| sf->mpidlNSRoot = NULL; |
| |
| if(sf->mpidl) /* do we have a pidl?*/ |
| { dwSize = 0; |
| if(sf->mpSFParent->mlpszFolder) |
| { dwSize += strlen(sf->mpSFParent->mlpszFolder) + 1; |
| } |
| dwSize += sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr,sf->mpidl,NULL,0); |
| sf->mlpszFolder = SHAlloc(dwSize); |
| if(sf->mlpszFolder) |
| { *(sf->mlpszFolder)=0x00; |
| if(sf->mpSFParent->mlpszFolder) |
| { strcpy(sf->mlpszFolder, sf->mpSFParent->mlpszFolder); |
| PathAddBackslash (sf->mlpszFolder); |
| } |
| sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr, sf->mpidl, sf->mlpszFolder+strlen(sf->mlpszFolder), dwSize-strlen(sf->mlpszFolder)); |
| } |
| } |
| |
| TRACE(shell,"-- (%p)->(%p,%p,parent=%s)\n",sf,pParent, pidl, debugstr_a(sf->mlpszFolder)); |
| return sf; |
| } |
| /************************************************************************** |
| * IShellFolder::QueryInterface |
| * PARAMETERS |
| * REFIID riid, //[in ] Requested InterfaceID |
| * LPVOID* ppvObject) //[out] Interface* to hold the result |
| */ |
| static HRESULT WINAPI IShellFolder_QueryInterface( |
| LPSHELLFOLDER this, REFIID riid, LPVOID *ppvObj) |
| { char xriid[50]; |
| WINE_StringFromCLSID((LPCLSID)riid,xriid); |
| TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj); |
| |
| *ppvObj = NULL; |
| |
| if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ |
| { *ppvObj = this; |
| } |
| else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/ |
| { *ppvObj = (IShellFolder*)this; |
| } |
| |
| if(*ppvObj) |
| { (*(LPSHELLFOLDER*)ppvObj)->lpvtbl->fnAddRef(this); |
| TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); |
| return S_OK; |
| } |
| TRACE(shell,"-- Interface: E_NOINTERFACE\n"); |
| return E_NOINTERFACE; |
| } |
| |
| /************************************************************************** |
| * IShellFolder::AddRef |
| */ |
| |
| static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER this) |
| { TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1); |
| return ++(this->ref); |
| } |
| |
| /************************************************************************** |
| * IShellFolder_Release |
| */ |
| static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER this) |
| { TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); |
| if (!--(this->ref)) |
| { TRACE(shell,"-- destroying IShellFolder(%p)\n",this); |
| |
| if (pdesktopfolder==this) |
| { pdesktopfolder=NULL; |
| TRACE(shell,"-- destroyed IShellFolder(%p) was Desktopfolder\n",this); |
| } |
| if (this->pPidlMgr) |
| { PidlMgr_Destructor(this->pPidlMgr); |
| } |
| if(this->mpidlNSRoot) |
| { SHFree(this->mpidlNSRoot); |
| } |
| if(this->mpidl) |
| { SHFree(this->mpidl); |
| } |
| if(this->mlpszFolder) |
| { SHFree(this->mlpszFolder); |
| } |
| |
| HeapFree(GetProcessHeap(),0,this); |
| |
| return 0; |
| } |
| return this->ref; |
| } |
| /************************************************************************** |
| * IShellFolder_ParseDisplayName |
| * PARAMETERS |
| * HWND hwndOwner, //[in ] Parent window for any message's |
| * LPBC pbc, //[in ] reserved |
| * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname. |
| * ULONG* pchEaten, //[out] (unicode) characters processed |
| * LPITEMIDLIST* ppidl, //[out] complex pidl to item |
| * ULONG* pdwAttributes //[out] items attributes |
| * |
| * FIXME: |
| * pdwAttributes: not used |
| */ |
| static HRESULT WINAPI IShellFolder_ParseDisplayName( |
| LPSHELLFOLDER this, |
| HWND32 hwndOwner, |
| LPBC pbcReserved, |
| LPOLESTR32 lpszDisplayName, |
| DWORD *pchEaten, |
| LPITEMIDLIST *ppidl, |
| DWORD *pdwAttributes) |
| { HRESULT hr=E_OUTOFMEMORY; |
| LPITEMIDLIST pidlFull=NULL, pidlTemp = NULL, pidlOld = NULL; |
| LPSTR pszNext=NULL; |
| CHAR szElement[MAX_PATH]; |
| BOOL32 bType; |
| |
| DWORD dwChars=lstrlen32W(lpszDisplayName) + 1; |
| LPSTR pszTemp=(LPSTR)HeapAlloc(GetProcessHeap(),0,dwChars * sizeof(CHAR)); |
| |
| TRACE(shell,"(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n", |
| this,hwndOwner,pbcReserved,lpszDisplayName,debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes); |
| |
| if(pszTemp) |
| { hr = E_FAIL; |
| WideCharToLocal32(pszTemp, lpszDisplayName, dwChars); |
| if(*pszTemp) |
| { if (strcmp(pszTemp,"Desktop")==0) |
| { pidlFull = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,2); |
| pidlFull->mkid.cb = 0; |
| } |
| else |
| { pidlFull = this->pPidlMgr->lpvtbl->fnCreateMyComputer(this->pPidlMgr); |
| |
| /* check if the lpszDisplayName is Folder or File*/ |
| bType = ! (GetFileAttributes32A(pszNext)&FILE_ATTRIBUTE_DIRECTORY); |
| pszNext = GetNextElement(pszTemp, szElement, MAX_PATH); |
| |
| pidlTemp = this->pPidlMgr->lpvtbl->fnCreateDrive(this->pPidlMgr,szElement); |
| pidlOld = pidlFull; |
| pidlFull = ILCombine(pidlFull,pidlTemp); |
| SHFree(pidlOld); |
| |
| if(pidlFull) |
| { while((pszNext=GetNextElement(pszNext, szElement, MAX_PATH))) |
| { if(!*pszNext && bType) |
| { pidlTemp = this->pPidlMgr->lpvtbl->fnCreateValue(this->pPidlMgr,szElement); |
| } |
| else |
| { pidlTemp = this->pPidlMgr->lpvtbl->fnCreateFolder(this->pPidlMgr,szElement); |
| } |
| pidlOld = pidlFull; |
| pidlFull = ILCombine(pidlFull,pidlTemp); |
| SHFree(pidlOld); |
| } |
| hr = S_OK; |
| } |
| } |
| } |
| } |
| HeapFree(GetProcessHeap(),0,pszTemp); |
| *ppidl = pidlFull; |
| return hr; |
| } |
| |
| /************************************************************************** |
| * IShellFolder_EnumObjects |
| * PARAMETERS |
| * HWND hwndOwner, //[in ] Parent Window |
| * DWORD grfFlags, //[in ] SHCONTF enumeration mask |
| * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface |
| */ |
| static HRESULT WINAPI IShellFolder_EnumObjects( |
| LPSHELLFOLDER this, |
| HWND32 hwndOwner, |
| DWORD dwFlags, |
| LPENUMIDLIST* ppEnumIDList) |
| { HRESULT hr; |
| TRACE(shell,"(%p)->(HWND=0x%08x,0x%08lx,%p)\n",this,hwndOwner,dwFlags,ppEnumIDList); |
| |
| *ppEnumIDList = NULL; |
| *ppEnumIDList = IEnumIDList_Constructor (this->mlpszFolder, dwFlags, &hr); |
| TRACE(shell,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList); |
| if(!*ppEnumIDList) |
| { return hr; |
| } |
| return S_OK; |
| } |
| /************************************************************************** |
| * IShellFolder_Initialize() |
| * IPersistFolder Method |
| */ |
| static HRESULT WINAPI IShellFolder_Initialize( |
| LPSHELLFOLDER this, |
| LPCITEMIDLIST pidl) |
| { TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); |
| if(this->mpidlNSRoot) |
| { SHFree(this->mpidlNSRoot); |
| this->mpidlNSRoot = NULL; |
| } |
| this->mpidlNSRoot=ILClone(pidl); |
| return S_OK; |
| } |
| |
| /************************************************************************** |
| * IShellFolder_BindToObject |
| * PARAMETERS |
| * LPCITEMIDLIST pidl, //[in ] complex pidl to open |
| * LPBC pbc, //[in ] reserved |
| * REFIID riid, //[in ] Initial Interface |
| * LPVOID* ppvObject //[out] Interface* |
| */ |
| static HRESULT WINAPI IShellFolder_BindToObject( |
| LPSHELLFOLDER this, |
| LPCITEMIDLIST pidl, |
| LPBC pbcReserved, |
| REFIID riid, |
| LPVOID * ppvOut) |
| { char xriid[50]; |
| HRESULT hr; |
| LPSHELLFOLDER pShellFolder; |
| |
| WINE_StringFromCLSID(riid,xriid); |
| |
| TRACE(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p)\n",this,pidl,pbcReserved,xriid,ppvOut); |
| |
| *ppvOut = NULL; |
| pShellFolder = IShellFolder_Constructor(this, pidl); |
| if(!pShellFolder) |
| return E_OUTOFMEMORY; |
| /* pShellFolder->lpvtbl->fnInitialize(pShellFolder, this->mpidlNSRoot);*/ |
| IShellFolder_Initialize(pShellFolder, this->mpidlNSRoot); |
| hr = pShellFolder->lpvtbl->fnQueryInterface(pShellFolder, riid, ppvOut); |
| pShellFolder->lpvtbl->fnRelease(pShellFolder); |
| TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut); |
| return hr; |
| } |
| |
| /************************************************************************** |
| * IShellFolder_BindToStorage |
| * PARAMETERS |
| * LPCITEMIDLIST pidl, //[in ] complex pidl to store |
| * LPBC pbc, //[in ] reserved |
| * REFIID riid, //[in ] Initial storage interface |
| * LPVOID* ppvObject //[out] Interface* returned |
| */ |
| static HRESULT WINAPI IShellFolder_BindToStorage( |
| LPSHELLFOLDER this, |
| LPCITEMIDLIST pidl, /*simple/complex pidl*/ |
| LPBC pbcReserved, |
| REFIID riid, |
| LPVOID *ppvOut) |
| { char xriid[50]; |
| WINE_StringFromCLSID(riid,xriid); |
| |
| FIXME(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",this,pidl,pbcReserved,xriid,ppvOut); |
| |
| *ppvOut = NULL; |
| return E_NOTIMPL; |
| } |
| |
| /************************************************************************** |
| * IShellFolder_CompareIDs |
| * |
| * PARMETERS |
| * LPARAM lParam, //[in ] Column? |
| * LPCITEMIDLIST pidl1, //[in ] simple pidl |
| * LPCITEMIDLIST pidl2) //[in ] simple pidl |
| * FIXME |
| * we have to handle simple pidl's only |
| */ |
| static HRESULT WINAPI IShellFolder_CompareIDs( |
| LPSHELLFOLDER this, |
| LPARAM lParam, |
| LPCITEMIDLIST pidl1, /*simple pidl*/ |
| LPCITEMIDLIST pidl2) /*simple pidl*/ |
| { CHAR szString1[MAX_PATH] = ""; |
| CHAR szString2[MAX_PATH] = ""; |
| int nReturn; |
| LPCITEMIDLIST pidlTemp1 = pidl1, pidlTemp2 = pidl2; |
| |
| TRACE(shell,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",this,lParam,pidl1,pidl2); |
| |
| /*Special case - If one of the items is a Path and the other is a File, always |
| make the Path come before the File.*/ |
| |
| /* get the last item in each list */ |
| while((this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp1))->mkid.cb) |
| pidlTemp1 = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp1); |
| while((this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp2))->mkid.cb) |
| pidlTemp2 = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp2); |
| |
| /* at this point, both pidlTemp1 and pidlTemp2 point to the last item in the list */ |
| if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1) != this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp2)) |
| { if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1)) |
| return 1; |
| return -1; |
| } |
| |
| this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl1,szString1,sizeof(szString1)); |
| this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl2,szString1,sizeof(szString2)); |
| nReturn = strcasecmp(szString1, szString2); |
| if(nReturn) |
| return nReturn; |
| |
| this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl1,szString1,sizeof(szString1)); |
| this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl2,szString2,sizeof(szString2)); |
| nReturn = strcasecmp(szString1, szString2); |
| if(nReturn) |
| return nReturn; |
| |
| this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl1,szString1,sizeof(szString1)); |
| this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl2,szString2,sizeof(szString2)); |
| return strcasecmp(szString1, szString2); |
| } |
| |
| /************************************************************************** |
| * IShellFolder_CreateViewObject |
| * Creates an View Object representing the ShellFolder |
| * IShellView / IShellBrowser / IContextMenu |
| * |
| * PARAMETERS |
| * HWND hwndOwner, // Handle of owner window |
| * REFIID riid, // Requested initial interface |
| * LPVOID* ppvObject) // Resultant interface* |
| * |
| * NOTES |
| * the same as SHCreateShellFolderViewEx ??? |
| */ |
| static HRESULT WINAPI IShellFolder_CreateViewObject( |
| LPSHELLFOLDER this, |
| HWND32 hwndOwner, |
| REFIID riid, |
| LPVOID *ppvOut) |
| { LPSHELLVIEW pShellView; |
| char xriid[50]; |
| HRESULT hr; |
| |
| WINE_StringFromCLSID(riid,xriid); |
| TRACE(shell,"(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",this,hwndOwner,xriid,ppvOut); |
| |
| *ppvOut = NULL; |
| |
| pShellView = IShellView_Constructor(this, this->mpidl); |
| if(!pShellView) |
| return E_OUTOFMEMORY; |
| hr = pShellView->lpvtbl->fnQueryInterface(pShellView, riid, ppvOut); |
| pShellView->lpvtbl->fnRelease(pShellView); |
| TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut); |
| return hr; |
| } |
| |
| /************************************************************************** |
| * IShellFolder_GetAttributesOf |
| * |
| * PARAMETERS |
| * UINT cidl, //[in ] num elements in pidl array |
| + LPCITEMIDLIST* apidl, //[in ] simple pidl array |
| * ULONG* rgfInOut) //[out] result array |
| * |
| * FIXME: quick hack |
| * Note: rgfInOut is documented as being an array of ULONGS. |
| * This does not seem to be the case. Testing this function using the shell to |
| * call it with cidl > 1 (by deleting multiple items) reveals that the shell |
| * passes ONE element in the array and writing to further elements will |
| * cause the shell to fail later. |
| */ |
| static HRESULT WINAPI IShellFolder_GetAttributesOf( |
| LPSHELLFOLDER this, |
| UINT32 cidl, |
| LPCITEMIDLIST *apidl, /*simple pidl's*/ |
| DWORD *rgfInOut) |
| { LPCITEMIDLIST * pidltemp; |
| DWORD i; |
| TRACE(shell,"(%p)->(%d,%p,%p)\n",this,cidl,apidl,rgfInOut); |
| |
| pidltemp=apidl; |
| *rgfInOut = 0x00; |
| i=cidl; |
| if ((! cidl )| (!apidl) | (!rgfInOut)) |
| return E_INVALIDARG; |
| |
| do |
| { if (*pidltemp) |
| { if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, *pidltemp)) |
| { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); |
| } |
| else if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, *pidltemp)) |
| { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER); |
| } |
| else if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, *pidltemp)) |
| { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM); |
| } |
| else if (this->pPidlMgr->lpvtbl->fnIsFolder(this->pPidlMgr, *pidltemp)) |
| { *rgfInOut |= (SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER); |
| } |
| else if (this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr, *pidltemp)) |
| { *rgfInOut |= (SFGAO_FILESYSTEM); |
| } |
| } |
| pidltemp++; |
| cidl--; |
| } while (cidl > 0 && *pidltemp); |
| |
| return S_OK; |
| } |
| /************************************************************************** |
| * IShellFolder_GetUIObjectOf |
| * |
| * PARAMETERS |
| * HWND hwndOwner, //[in ] Parent window for any output |
| * UINT cidl, //[in ] array size |
| * LPCITEMIDLIST* apidl, //[in ] simple pidl array |
| * REFIID riid, //[in ] Requested Interface |
| * UINT* prgfInOut, //[ ] reserved |
| * LPVOID* ppvObject) //[out] Resulting Interface |
| * |
| * NOTES |
| * This function gets asked to return "view objects" for one or more (multiple select) |
| * items: |
| * The viewobject typically is an COM object with one of the following interfaces: |
| * IExtractIcon,IDataObject,IContextMenu |
| * In order to support icon positions in the default Listview your DataObject |
| * must implement the SetData method (in addition to GetData :) - the shell passes |
| * a barely documented "Icon positions" structure to SetData when the drag starts, |
| * and GetData's it if the drop is in another explorer window that needs the positions. |
| */ |
| static HRESULT WINAPI IShellFolder_GetUIObjectOf( |
| LPSHELLFOLDER this, |
| HWND32 hwndOwner, |
| UINT32 cidl, |
| LPCITEMIDLIST * apidl, /* simple pidl's*/ |
| REFIID riid, |
| UINT32 * prgfInOut, |
| LPVOID * ppvOut) |
| { char xclsid[50]; |
| |
| WINE_StringFromCLSID(riid,xclsid); |
| |
| FIXME(shell,"(%p)->(%u,%u,pidl=%p,\n\tIID:%s,%p,%p),stub!\n", |
| this,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut); |
| |
| *ppvOut = NULL; |
| return E_NOTIMPL; |
| } |
| /************************************************************************** |
| * IShellFolder_GetDisplayNameOf |
| * Retrieves the display name for the specified file object or subfolder |
| * |
| * PARAMETERS |
| * LPCITEMIDLIST pidl, //[in ] complex pidl to item |
| * DWORD dwFlags, //[in ] SHGNO formatting flags |
| * LPSTRRET lpName) //[out] Returned display name |
| * |
| * FIXME |
| * if the name is in the pidl the ret value should be a STRRET_OFFSET |
| */ |
| #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00) |
| #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF) |
| |
| static HRESULT WINAPI IShellFolder_GetDisplayNameOf( |
| LPSHELLFOLDER this, |
| LPCITEMIDLIST pidl, /* simple/complex pidl*/ |
| DWORD dwFlags, |
| LPSTRRET lpName) |
| { CHAR szText[MAX_PATH]; |
| CHAR szTemp[MAX_PATH]; |
| CHAR szSpecial[MAX_PATH]; |
| CHAR szDrive[MAX_PATH]; |
| DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags; |
| LPITEMIDLIST pidlTemp=NULL; |
| BOOL32 bSimplePidl=FALSE; |
| |
| TRACE(shell,"(%p)->(pidl=%p,0x%08lx,%p)\n",this,pidl,dwFlags,lpName); |
| |
| if (!pidl) |
| { return E_OUTOFMEMORY; |
| } |
| |
| szSpecial[0]=0x00; |
| szDrive[0]=0x00; |
| |
| /* test if simple(relative) or complex(absolute) pidl */ |
| pidlTemp = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidl); |
| if (pidlTemp->mkid.cb==0x00) |
| { bSimplePidl = TRUE; |
| } |
| if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, pidl)) |
| { strcpy (szText,"Desktop"); |
| } |
| else |
| { if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, pidl)) |
| { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidl, szSpecial, MAX_PATH); |
| } |
| if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, pidl)) |
| { pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl); |
| if (pidlTemp) |
| { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH); |
| } |
| if ( dwFlags==SHGDN_NORMAL || dwFlags==SHGDN_INFOLDER) |
| { GetVolumeInformation32A(szTemp,szDrive,MAX_PATH,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0); |
| if (szTemp[2]=='\\') |
| { szTemp[2]=0x00; |
| } |
| strcat (szDrive," ("); |
| strcat (szDrive,szTemp); |
| strcat (szDrive,")"); |
| } |
| else |
| { PathAddBackslash (szTemp); |
| strcpy(szDrive,szTemp); |
| } |
| } |
| |
| switch(dwFlags) |
| { case SHGDN_NORMAL: |
| this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH); |
| break; |
| case SHGDN_INFOLDER: |
| pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl); |
| if (pidlTemp) |
| { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szText, MAX_PATH); |
| } |
| break; |
| case SHGDN_FORPARSING: |
| if (bSimplePidl) |
| { /* if the IShellFolder has parents, get the path from the |
| parent and add the ItemName*/ |
| szText[0]=0x00; |
| if (this->mlpszFolder && strlen (this->mlpszFolder)) |
| { if (strcmp(this->mlpszFolder,"My Computer")) |
| { strcpy (szText,this->mlpszFolder); |
| PathAddBackslash (szText); |
| } |
| } |
| pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl); |
| if (pidlTemp) |
| { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH ); |
| } |
| strcat(szText,szTemp); |
| } |
| else |
| { /* if the pidl is absolute, get everything from the pidl*/ |
| this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH); |
| } |
| break; |
| default: return E_INVALIDARG; |
| } |
| if ((szText[0]==0x00 && szDrive[0]!=0x00)|| (bSimplePidl && szDrive[0]!=0x00)) |
| { strcpy(szText,szDrive); |
| } |
| if (szText[0]==0x00 && szSpecial[0]!=0x00) |
| { strcpy(szText,szSpecial); |
| } |
| } |
| |
| TRACE(shell,"-- (%p)->(%s,%s,%s)\n",this,szSpecial,szDrive,szText); |
| |
| if(!(lpName)) |
| { return E_OUTOFMEMORY; |
| } |
| lpName->uType = STRRET_CSTR; |
| strcpy(lpName->u.cStr,szText); |
| return S_OK; |
| } |
| |
| /************************************************************************** |
| * IShellFolder_SetNameOf |
| * Changes the name of a file object or subfolder, possibly changing its item |
| * identifier in the process. |
| * |
| * PARAMETERS |
| * HWND hwndOwner, //[in ] Owner window for output |
| * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change |
| * LPCOLESTR lpszName, //[in ] the items new display name |
| * DWORD dwFlags, //[in ] SHGNO formatting flags |
| * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned |
| */ |
| static HRESULT WINAPI IShellFolder_SetNameOf( |
| LPSHELLFOLDER this, |
| HWND32 hwndOwner, |
| LPCITEMIDLIST pidl, /*simple pidl*/ |
| LPCOLESTR32 lpName, |
| DWORD dw, |
| LPITEMIDLIST *pPidlOut) |
| { FIXME(shell,"(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n", |
| this,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut); |
| return E_NOTIMPL; |
| } |
| |
| /************************************************************************** |
| * IShellLink Implementation |
| */ |
| static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*); |
| static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK); |
| static ULONG WINAPI IShellLink_Release(LPSHELLLINK); |
| |
| /************************************************************************** |
| * IShellLink_VTable |
| */ |
| static struct IShellLink_VTable slvt = { |
| IShellLink_QueryInterface, |
| IShellLink_AddRef, |
| IShellLink_Release, |
| (void *)0xcafe0004, |
| (void *)0xcafe0005, |
| (void *)0xcafe0006, |
| (void *)0xcafe0007, |
| (void *)0xcafe0008, |
| (void *)0xcafe0009, |
| (void *)0xcafe0010, |
| (void *)0xcafe0011, |
| (void *)0xcafe0012, |
| (void *)0xcafe0013, |
| (void *)0xcafe0014, |
| (void *)0xcafe0015, |
| (void *)0xcafe0016, |
| (void *)0xcafe0017, |
| (void *)0xcafe0018, |
| (void *)0xcafe0019, |
| (void *)0xcafe0020, |
| (void *)0xcafe0021 |
| }; |
| |
| /************************************************************************** |
| * IShellLink_Constructor |
| */ |
| LPSHELLLINK IShellLink_Constructor() |
| { LPSHELLLINK sl; |
| |
| sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink)); |
| sl->ref = 1; |
| sl->lpvtbl = &slvt; |
| TRACE(shell,"(%p)->()\n",sl); |
| return sl; |
| } |
| |
| /************************************************************************** |
| * IShellLink::QueryInterface |
| */ |
| static HRESULT WINAPI IShellLink_QueryInterface( |
| LPSHELLLINK this, REFIID riid, LPVOID *ppvObj) |
| { char xriid[50]; |
| WINE_StringFromCLSID((LPCLSID)riid,xriid); |
| TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid); |
| |
| *ppvObj = NULL; |
| |
| if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ |
| { *ppvObj = this; |
| } |
| else if(IsEqualIID(riid, &IID_IShellLink)) /*IShellLink*/ |
| { *ppvObj = (LPSHELLLINK)this; |
| } |
| |
| if(*ppvObj) |
| { (*(LPSHELLLINK*)ppvObj)->lpvtbl->fnAddRef(this); |
| TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); |
| return S_OK; |
| } |
| TRACE(shell,"-- Interface: E_NOINTERFACE\n"); |
| return E_NOINTERFACE; |
| } |
| /****************************************************************************** |
| * IShellLink_AddRef |
| */ |
| static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK this) |
| { TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); |
| return ++(this->ref); |
| } |
| /****************************************************************************** |
| * IClassFactory_Release |
| */ |
| static ULONG WINAPI IShellLink_Release(LPSHELLLINK this) |
| { TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref); |
| if (!--(this->ref)) |
| { TRACE(shell,"-- destroying IShellLink(%p)\n",this); |
| HeapFree(GetProcessHeap(),0,this); |
| return 0; |
| } |
| return this->ref; |
| } |
| |
| |
| /************************************************************************** |
| * INTERNAL CLASS pidlmgr |
| */ |
| LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR); |
| LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR); |
| LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR,LPCSTR); |
| LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR,LPCSTR); |
| LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR,LPCSTR); |
| /*void PidlMgr_Delete(LPPIDLMGR,LPITEMIDLIST);*/ |
| LPITEMIDLIST PidlMgr_GetNextItem(LPPIDLMGR,LPITEMIDLIST); |
| BOOL32 PidlMgr_GetDesktop(LPPIDLMGR,LPCITEMIDLIST,LPSTR); |
| BOOL32 PidlMgr_GetDrive(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16); |
| LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR,LPCITEMIDLIST); |
| DWORD PidlMgr_GetItemText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16); |
| BOOL32 PidlMgr_IsDesktop(LPPIDLMGR,LPCITEMIDLIST); |
| BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR,LPCITEMIDLIST); |
| BOOL32 PidlMgr_IsDrive(LPPIDLMGR,LPCITEMIDLIST); |
| BOOL32 PidlMgr_IsFolder(LPPIDLMGR,LPCITEMIDLIST); |
| BOOL32 PidlMgr_IsValue(LPPIDLMGR,LPCITEMIDLIST); |
| BOOL32 PidlMgr_HasFolders(LPPIDLMGR,LPSTR,LPCITEMIDLIST); |
| DWORD PidlMgr_GetFolderText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD); |
| DWORD PidlMgr_GetValueText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD); |
| BOOL32 PidlMgr_GetValueType(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPDWORD); |
| DWORD PidlMgr_GetDataText(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPSTR,DWORD); |
| DWORD PidlMgr_GetPidlPath(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD); |
| LPITEMIDLIST PidlMgr_Create(LPPIDLMGR,PIDLTYPE,LPVOID,UINT16); |
| DWORD PidlMgr_GetData(LPPIDLMGR,PIDLTYPE,LPCITEMIDLIST,LPVOID,UINT16); |
| LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR,LPCITEMIDLIST); |
| BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR,LPITEMIDLIST,LPITEMIDLIST*,LPITEMIDLIST*); |
| |
| static struct PidlMgr_VTable pmgrvt = { |
| PidlMgr_CreateDesktop, |
| PidlMgr_CreateMyComputer, |
| PidlMgr_CreateDrive, |
| PidlMgr_CreateFolder, |
| PidlMgr_CreateValue, |
| /* PidlMgr_Delete,*/ |
| PidlMgr_GetNextItem, |
| PidlMgr_GetDesktop, |
| PidlMgr_GetDrive, |
| PidlMgr_GetLastItem, |
| PidlMgr_GetItemText, |
| PidlMgr_IsDesktop, |
| PidlMgr_IsMyComputer, |
| PidlMgr_IsDrive, |
| PidlMgr_IsFolder, |
| PidlMgr_IsValue, |
| PidlMgr_HasFolders, |
| PidlMgr_GetFolderText, |
| PidlMgr_GetValueText, |
| PidlMgr_GetValueType, |
| PidlMgr_GetDataText, |
| PidlMgr_GetPidlPath, |
| PidlMgr_Create, |
| PidlMgr_GetData, |
| PidlMgr_GetDataPointer, |
| PidlMgr_SeparatePathAndValue |
| }; |
| /************************************************************************** |
| * PidlMgr_Constructor |
| */ |
| LPPIDLMGR PidlMgr_Constructor() |
| { LPPIDLMGR pmgr; |
| pmgr = (LPPIDLMGR)HeapAlloc(GetProcessHeap(),0,sizeof(pidlmgr)); |
| pmgr->lpvtbl = &pmgrvt; |
| TRACE(shell,"(%p)->()\n",pmgr); |
| /** FIXME DllRefCount++;*/ |
| return pmgr; |
| } |
| /************************************************************************** |
| * PidlMgr_Destructor |
| */ |
| void PidlMgr_Destructor(LPPIDLMGR this) |
| { HeapFree(GetProcessHeap(),0,this); |
| TRACE(shell,"(%p)->()\n",this); |
| /** FIXME DllRefCount--;*/ |
| } |
| |
| /************************************************************************** |
| * PidlMgr_CreateDesktop() |
| * PidlMgr_CreateMyComputer() |
| * PidlMgr_CreateDrive() |
| * PidlMgr_CreateFolder() |
| * PidlMgr_CreateValue() |
| */ |
| LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR this) |
| { TRACE(shell,"(%p)->()\n",this); |
| return PidlMgr_Create(this,PT_DESKTOP, NULL, 0); |
| } |
| LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR this) |
| { TRACE(shell,"(%p)->()\n",this); |
| return PidlMgr_Create(this,PT_MYCOMP, (void *)"My Computer", strlen ("My Computer")+1); |
| } |
| LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR this, LPCSTR lpszNew) |
| { char sTemp[4]; |
| strncpy (sTemp,lpszNew,4); |
| sTemp[2]='\\'; |
| sTemp[3]=0x00; |
| TRACE(shell,"(%p)->(%s)\n",this,sTemp); |
| return PidlMgr_Create(this,PT_DRIVE,(LPVOID)&sTemp[0],4); |
| } |
| LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR this, LPCSTR lpszNew) |
| { TRACE(shell,"(%p)->(%s)\n",this,lpszNew); |
| return PidlMgr_Create(this,PT_FOLDER, (LPVOID)lpszNew, strlen(lpszNew)+1); |
| } |
| LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR this,LPCSTR lpszNew) |
| { TRACE(shell,"(%p)->(%s)\n",this,lpszNew); |
| return PidlMgr_Create(this,PT_VALUE, (LPVOID)lpszNew, strlen(lpszNew)+1); |
| } |
| /************************************************************************** |
| * PidlMgr_Delete() |
| * Deletes a PIDL |
| */ |
| /*void PidlMgr_Delete(LPPIDLMGR this,LPITEMIDLIST pidl) |
| { TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); |
| HeapFree(GetProcessHeap(),0,pidl); |
| } |
| */ |
| /************************************************************************** |
| * PidlMgr_GetNextItem() |
| */ |
| LPITEMIDLIST PidlMgr_GetNextItem(LPPIDLMGR this, LPITEMIDLIST pidl) |
| { LPITEMIDLIST nextpidl; |
| |
| TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); |
| if(pidl) |
| { nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb); |
| /* TRACE(shell,"-- (%p)->(next pidl=%p)\n",this,nextpidl);*/ |
| return nextpidl; |
| } |
| else |
| { return (NULL); |
| } |
| } |
| /************************************************************************** |
| * PidlMgr_GetDesktop() |
| * |
| * FIXME: quick hack |
| */ |
| BOOL32 PidlMgr_GetDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut) |
| { TRACE(shell,"(%p)->(%p %p)\n",this,pidl,pOut); |
| return (BOOL32)PidlMgr_GetData(this,PT_DESKTOP, pidl, (LPVOID)pOut, 255); |
| } |
| /************************************************************************** |
| * PidlMgr_GetDrive() |
| * |
| * FIXME: quick hack |
| */ |
| BOOL32 PidlMgr_GetDrive(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize) |
| { LPITEMIDLIST pidlTemp=NULL; |
| |
| TRACE(shell,"(%p)->(%p,%p,%u)\n",this,pidl,pOut,uSize); |
| if(PidlMgr_IsMyComputer(this,pidl)) |
| { pidlTemp = PidlMgr_GetNextItem(this,pidl); |
| } |
| else if (pidlTemp && PidlMgr_IsDrive(this,pidlTemp)) |
| { return (BOOL32)PidlMgr_GetData(this,PT_DRIVE, pidlTemp, (LPVOID)pOut, uSize); |
| } |
| return FALSE; |
| } |
| /************************************************************************** |
| * PidlMgr_GetLastItem() |
| * Gets the last item in the list |
| */ |
| LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR this,LPCITEMIDLIST pidl) |
| { LPITEMIDLIST pidlLast = NULL; |
| |
| TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl); |
| |
| if(pidl) |
| { while(pidl->mkid.cb) |
| { pidlLast = (LPITEMIDLIST)pidl; |
| pidl = PidlMgr_GetNextItem(this,pidl); |
| } |
| } |
| return pidlLast; |
| } |
| /************************************************************************** |
| * PidlMgr_GetItemText() |
| * Gets the text for only this item |
| */ |
| DWORD PidlMgr_GetItemText(LPPIDLMGR this,LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize) |
| { TRACE(shell,"(%p)->(pidl=%p %p %x)\n",this,pidl,lpszText,uSize); |
| if (PidlMgr_IsMyComputer(this, pidl)) |
| { return PidlMgr_GetData(this,PT_MYCOMP, pidl, (LPVOID)lpszText, uSize); |
| } |
| if (PidlMgr_IsDrive(this, pidl)) |
| { return PidlMgr_GetData(this,PT_DRIVE, pidl, (LPVOID)lpszText, uSize); |
| } |
| return PidlMgr_GetData(this,PT_TEXT, pidl, (LPVOID)lpszText, uSize); |
| } |
| /************************************************************************** |
| * PidlMgr_IsDesktop() |
| * PidlMgr_IsDrive() |
| * PidlMgr_IsFolder() |
| * PidlMgr_IsValue() |
| */ |
| BOOL32 PidlMgr_IsDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl) |
| { TRACE(shell,"%p->(%p)\n",this,pidl); |
| |
| if (! pidl) |
| return FALSE; |
| |
| return ( pidl->mkid.cb == 0x00 ); |
| } |
| |
| BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR this,LPCITEMIDLIST pidl) |
| { LPPIDLDATA pData; |
| TRACE(shell,"%p->(%p)\n",this,pidl); |
| |
| if (! pidl) |
| return FALSE; |
| |
| pData = PidlMgr_GetDataPointer(this,pidl); |
| return (PT_MYCOMP == pData->type); |
| } |
| |
| BOOL32 PidlMgr_IsDrive(LPPIDLMGR this,LPCITEMIDLIST pidl) |
| { LPPIDLDATA pData; |
| TRACE(shell,"%p->(%p)\n",this,pidl); |
| |
| if (! pidl) |
| return FALSE; |
| |
| pData = PidlMgr_GetDataPointer(this,pidl); |
| return (PT_DRIVE == pData->type); |
| } |
| |
| BOOL32 PidlMgr_IsFolder(LPPIDLMGR this,LPCITEMIDLIST pidl) |
| { LPPIDLDATA pData; |
| TRACE(shell,"%p->(%p)\n",this,pidl); |
| |
| if (! pidl) |
| return FALSE; |
| |
| pData = PidlMgr_GetDataPointer(this,pidl); |
| return (PT_FOLDER == pData->type); |
| } |
| |
| BOOL32 PidlMgr_IsValue(LPPIDLMGR this,LPCITEMIDLIST pidl) |
| { LPPIDLDATA pData; |
| TRACE(shell,"%p->(%p)\n",this,pidl); |
| |
| if (! pidl) |
| return FALSE; |
| |
| pData = PidlMgr_GetDataPointer(this,pidl); |
| return (PT_VALUE == pData->type); |
| } |
| /************************************************************************** |
| * PidlMgr_HasFolders() |
| * fixme: quick hack |
| */ |
| BOOL32 PidlMgr_HasFolders(LPPIDLMGR this, LPSTR pszPath, LPCITEMIDLIST pidl) |
| { BOOL32 bResult= FALSE; |
| WIN32_FIND_DATA32A stffile; |
| HANDLE32 hFile; |
| |
| TRACE (shell,"(%p)->%p %p\n",this, pszPath, pidl); |
| |
| hFile = FindFirstFile32A(pszPath,&stffile); |
| do |
| { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) |
| { bResult= TRUE; |
| } |
| } while( FindNextFile32A(hFile,&stffile)); |
| FindClose32 (hFile); |
| |
| return bResult; |
| } |
| |
| |
| /************************************************************************** |
| * PidlMgr_GetFolderText() |
| * Creates a Path string from a PIDL, filtering out the special Folders |
| */ |
| DWORD PidlMgr_GetFolderText(LPPIDLMGR this,LPCITEMIDLIST pidl, |
| LPSTR lpszPath, DWORD dwSize) |
| { LPITEMIDLIST pidlTemp; |
| DWORD dwCopied = 0; |
| |
| TRACE(shell,"(%p)->(%p)\n",this,pidl); |
| |
| if(!pidl) |
| { return 0; |
| } |
| |
| if(PidlMgr_IsMyComputer(this,pidl)) |
| { pidlTemp = PidlMgr_GetNextItem(this,pidl); |
| TRACE(shell,"-- (%p)->skip My Computer\n",this); |
| } |
| else |
| { pidlTemp = (LPITEMIDLIST)pidl; |
| } |
| |
| //if this is NULL, return the required size of the buffer |
| if(!lpszPath) |
| { while(pidlTemp->mkid.cb) |
| { LPPIDLDATA pData = PidlMgr_GetDataPointer(this,pidlTemp); |
| |
| //add the length of this item plus one for the backslash |
| dwCopied += strlen(pData->szText) + 1; /* fixme pData->szText is not every time a string*/ |
| |
| pidlTemp = PidlMgr_GetNextItem(this,pidlTemp); |
| } |
| |
| //add one for the NULL terminator |
| TRACE(shell,"-- (%p)->(size=%lu)\n",this,dwCopied); |
| return dwCopied + 1; |
| } |
| |
| *lpszPath = 0; |
| |
| while(pidlTemp->mkid.cb && (dwCopied < dwSize)) |
| { LPPIDLDATA pData = PidlMgr_GetDataPointer(this,pidlTemp); |
| |
| //if this item is a value, then skip it and finish |
| if(PT_VALUE == pData->type) |
| { break; |
| } |
| |
| strcat(lpszPath, pData->szText); |
| strcat(lpszPath, "\\"); |
| dwCopied += strlen(pData->szText) + 1; |
| pidlTemp = PidlMgr_GetNextItem(this,pidlTemp); |
| |
| TRACE(shell,"-- (%p)->(size=%lu,%s)\n",this,dwCopied,lpszPath); |
| } |
| |
| //remove the last backslash if necessary |
| if(dwCopied) |
| { if(*(lpszPath + strlen(lpszPath) - 1) == '\\') |
| { *(lpszPath + strlen(lpszPath) - 1) = 0; |
| dwCopied--; |
| } |
| } |
| TRACE(shell,"-- (%p)->(path=%s)\n",this,lpszPath); |
| return dwCopied; |
| } |
| |
| |
| /************************************************************************** |
| * PidlMgr_GetValueText() |
| * Gets the text for the last item in the list |
| */ |
| DWORD PidlMgr_GetValueText(LPPIDLMGR this, |
| LPCITEMIDLIST pidl, LPSTR lpszValue, DWORD dwSize) |
| { LPITEMIDLIST pidlTemp=pidl; |
| CHAR szText[MAX_PATH]; |
| |
| TRACE(shell,"(%p)->(pidl=%p %p 0x%08lx)\n",this,pidl,lpszValue,dwSize); |
| |
| if(!pidl) |
| { return 0; |
| } |
| |
| while(pidlTemp->mkid.cb && !PidlMgr_IsValue(this,pidlTemp)) |
| { pidlTemp = PidlMgr_GetNextItem(this,pidlTemp); |
| } |
| |
| if(!pidlTemp->mkid.cb) |
| { return 0; |
| } |
| |
| PidlMgr_GetItemText(this, pidlTemp, szText, sizeof(szText)); |
| |
| if(!lpszValue) |
| { return strlen(szText) + 1; |
| } |
| strcpy(lpszValue, szText); |
| TRACE(shell,"-- (%p)->(pidl=%p %p=%s 0x%08lx)\n",this,pidl,lpszValue,lpszValue,dwSize); |
| return strlen(lpszValue); |
| } |
| /************************************************************************** |
| * PidlMgr_GetValueType() |
| */ |
| BOOL32 PidlMgr_GetValueType( LPPIDLMGR this, |
| LPCITEMIDLIST pidlPath, |
| LPCITEMIDLIST pidlValue, |
| LPDWORD pdwType) |
| { LPSTR lpszFolder, |
| lpszValueName; |
| DWORD dwNameSize; |
| |
| FIXME(shell,"(%p)->(%p %p %p) stub\n",this,pidlPath,pidlValue,pdwType); |
| |
| if(!pidlPath) |
| { return FALSE; |
| } |
| |
| if(!pidlValue) |
| { return FALSE; |
| } |
| |
| if(!pdwType) |
| { return FALSE; |
| } |
| |
| //get the Desktop |
| //PidlMgr_GetDesktop(this,pidlPath); |
| |
| /* fixme: add the driveletter here*/ |
| |
| //assemble the Folder string |
| dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0); |
| lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); |
| if(!lpszFolder) |
| { return FALSE; |
| } |
| PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize); |
| |
| //assemble the value name |
| dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0); |
| lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); |
| if(!lpszValueName) |
| { HeapFree(GetProcessHeap(),0,lpszFolder); |
| return FALSE; |
| } |
| PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize); |
| |
| /* fixme: we've got the path now do something with it |
| -like get the filetype*/ |
| |
| pdwType=NULL; |
| |
| HeapFree(GetProcessHeap(),0,lpszFolder); |
| HeapFree(GetProcessHeap(),0,lpszValueName); |
| return TRUE; |
| } |
| /************************************************************************** |
| * PidlMgr_GetDataText() |
| */ |
| DWORD PidlMgr_GetDataText( LPPIDLMGR this, |
| LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlValue, LPSTR lpszOut, DWORD dwOutSize) |
| { LPSTR lpszFolder, |
| lpszValueName; |
| DWORD dwNameSize; |
| |
| FIXME(shell,"(%p)->(pidl=%p pidl=%p) stub\n",this,pidlPath,pidlValue); |
| |
| if(!lpszOut || !pidlPath || !pidlValue) |
| { return FALSE; |
| } |
| |
| /* fixme: get the driveletter*/ |
| |
| //assemble the Folder string |
| dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0); |
| lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); |
| if(!lpszFolder) |
| { return FALSE; |
| } |
| PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize); |
| |
| //assemble the value name |
| dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0); |
| lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize); |
| if(!lpszValueName) |
| { HeapFree(GetProcessHeap(),0,lpszFolder); |
| return FALSE; |
| } |
| PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize); |
| |
| /* fixme: we've got the path now do something with it*/ |
| |
| HeapFree(GetProcessHeap(),0,lpszFolder); |
| HeapFree(GetProcessHeap(),0,lpszValueName); |
| |
| TRACE(shell,"-- (%p)->(%p=%s 0x%08lx)\n",this,lpszOut,lpszOut,dwOutSize); |
| |
| return TRUE; |
| } |
| |
| /************************************************************************** |
| * CPidlMgr::GetPidlPath() |
| * Create a string that includes the Drive name, the folder text and |
| * the value text. |
| */ |
| DWORD PidlMgr_GetPidlPath(LPPIDLMGR this, |
| LPCITEMIDLIST pidl, LPSTR lpszOut, DWORD dwOutSize) |
| { LPSTR lpszTemp; |
| WORD len; |
| |
| TRACE(shell,"(%p)->(%p,%lu)\n",this,lpszOut,dwOutSize); |
| |
| if(!lpszOut) |
| { return 0; |
| } |
| |
| *lpszOut = 0; |
| lpszTemp = lpszOut; |
| |
| dwOutSize -= PidlMgr_GetFolderText(this,pidl, lpszTemp, dwOutSize); |
| |
| //add a backslash if necessary |
| len = strlen(lpszTemp); |
| if (len && lpszTemp[len-1]!='\\') |
| { lpszTemp[len+0]='\\'; |
| lpszTemp[len+1]='\0'; |
| dwOutSize--; |
| } |
| |
| lpszTemp = lpszOut + strlen(lpszOut); |
| |
| //add the value string |
| PidlMgr_GetValueText(this,pidl, lpszTemp, dwOutSize); |
| |
| //remove the last backslash if necessary |
| if(*(lpszOut + strlen(lpszOut) - 1) == '\\') |
| { *(lpszOut + strlen(lpszOut) - 1) = 0; |
| } |
| |
| TRACE(shell,"-- (%p)->(%p=%s,%lu)\n",this,lpszOut,lpszOut,dwOutSize); |
| |
| return strlen(lpszOut); |
| |
| } |
| |
| /************************************************************************** |
| * PidlMgr_Create() |
| * Creates a new PIDL |
| * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE |
| * pIn = data |
| * uInSize = size of data |
| */ |
| |
| LPITEMIDLIST PidlMgr_Create(LPPIDLMGR this,PIDLTYPE type, LPVOID pIn, UINT16 uInSize) |
| { LPITEMIDLIST pidlOut=NULL; |
| UINT16 uSize; |
| LPITEMIDLIST pidlTemp=NULL; |
| LPPIDLDATA pData; |
| |
| TRACE(shell,"(%p)->(%x %p %x)\n",this,type,pIn,uInSize); |
| |
| if ( type == PT_DESKTOP) |
| { pidlOut = SHAlloc(2); |
| pidlOut->mkid.cb=0x0000; |
| return pidlOut; |
| } |
| |
| if (! pIn) |
| { return NULL; |
| } |
| |
| uSize = 2 + (sizeof(PIDLTYPE)) + uInSize + 2; /* cb + PIDLTYPE + uInSize +2 */ |
| pidlOut = SHAlloc(uSize); |
| pidlTemp = pidlOut; |
| if(pidlOut) |
| { pidlTemp->mkid.cb = uSize - 2; |
| pData =(LPPIDLDATA) &(pidlTemp->mkid.abID[0]); |
| pData->type = type; |
| switch(type) |
| { case PT_MYCOMP: |
| memcpy(pData->szText, pIn, uInSize); |
| TRACE(shell,"- (%p)->create My Computer: %s\n",this,debugstr_a(pData->szText)); |
| break; |
| case PT_DRIVE: |
| memcpy(pData->szText, pIn, uInSize); |
| TRACE(shell,"- (%p)->create Drive: %s\n",this,debugstr_a(pData->szText)); |
| break; |
| case PT_FOLDER: |
| case PT_VALUE: |
| memcpy(pData->szText, pIn, uInSize); |
| TRACE(shell,"- (%p)->create Value: %s\n",this,debugstr_a(pData->szText)); |
| break; |
| default: |
| FIXME(shell,"- (%p) wrong argument\n",this); |
| break; |
| } |
| |
| pidlTemp = PidlMgr_GetNextItem(this,pidlTemp); |
| pidlTemp->mkid.cb = 0x00; |
| } |
| TRACE(shell,"-- (%p)->(pidl=%p, size=%u)\n",this,pidlOut,uSize-2); |
| return pidlOut; |
| } |
| /************************************************************************** |
| * PidlMgr_GetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16) |
| */ |
| DWORD PidlMgr_GetData( |
| LPPIDLMGR this, |
| PIDLTYPE type, |
| LPCITEMIDLIST pidl, |
| LPVOID pOut, |
| UINT16 uOutSize) |
| { LPPIDLDATA pData; |
| DWORD dwReturn=0; |
| |
| TRACE(shell,"(%p)->(%x %p %p %x)\n",this,type,pidl,pOut,uOutSize); |
| |
| if(!pidl) |
| { return 0; |
| } |
| |
| pData = PidlMgr_GetDataPointer(this,pidl); |
| |
| //copy the data |
| switch(type) |
| { case PT_MYCOMP: if(uOutSize < 1) |
| return 0; |
| if(PT_MYCOMP != pData->type) |
| return 0; |
| *(LPSTR)pOut = 0; |
| strncpy((LPSTR)pOut, "My Computer", uOutSize); |
| dwReturn = strlen((LPSTR)pOut); |
| break; |
| |
| case PT_DRIVE: if(uOutSize < 1) |
| return 0; |
| if(PT_DRIVE != pData->type) |
| return 0; |
| *(LPSTR)pOut = 0; |
| strncpy((LPSTR)pOut, pData->szText, uOutSize); |
| dwReturn = strlen((LPSTR)pOut); |
| break; |
| |
| case PT_FOLDER: |
| case PT_VALUE: |
| case PT_TEXT: *(LPSTR)pOut = 0; |
| strncpy((LPSTR)pOut, pData->szText, uOutSize); |
| dwReturn = strlen((LPSTR)pOut); |
| break; |
| default: break; |
| } |
| TRACE(shell,"-- (%p)->(%p=%s 0x%08lx)\n",this,pOut,(char*)pOut,dwReturn); |
| return dwReturn; |
| } |
| |
| |
| /************************************************************************** |
| * PidlMgr_GetDataPointer() |
| */ |
| LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR this,LPITEMIDLIST pidl) |
| { if(!pidl) |
| { return NULL; |
| } |
| TRACE (shell,"(%p)->(%p)\n" ,this, pidl); |
| return (LPPIDLDATA)(pidl->mkid.abID); |
| } |
| |
| /************************************************************************** |
| * CPidlMgr_SeparatePathAndValue) |
| * Creates a separate path and value PIDL from a fully qualified PIDL. |
| */ |
| BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR this, |
| LPITEMIDLIST pidlFQ, LPITEMIDLIST *ppidlPath, LPITEMIDLIST *ppidlValue) |
| { LPITEMIDLIST pidlTemp; |
| TRACE (shell,"(%p)->(pidl=%p pidl=%p pidl=%p)",this,pidlFQ,ppidlPath,ppidlValue); |
| if(!pidlFQ) |
| { return FALSE; |
| } |
| |
| *ppidlValue = PidlMgr_GetLastItem(this,pidlFQ); |
| |
| if(!PidlMgr_IsValue(this,*ppidlValue)) |
| { return FALSE; |
| } |
| |
| *ppidlValue = ILClone(*ppidlValue); |
| *ppidlPath = ILClone(pidlFQ); |
| |
| pidlTemp = PidlMgr_GetLastItem(this,*ppidlPath); |
| pidlTemp->mkid.cb = 0x00; |
| |
| return TRUE; |
| } |