RemotePidlManager.cpp

Go to the documentation of this file.
00001 /*  Manage creation/manipulation of PIDLs for files/folder in remote directory
00002 
00003     Copyright (C) 2007  Alexander Lamaison <awl03@doc.ic.ac.uk>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License along
00016     with this program; if not, write to the Free Software Foundation, Inc.,
00017     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00018 */
00019 
00020 #include "stdafx.h"
00021 #include "RemotePidlManager.h"
00022 
00041 HRESULT CRemotePidlManager::Create(
00042         __in LPCWSTR pwszPath, __in LPCWSTR pwszOwner, __in LPCWSTR pwszGroup,
00043         __in DWORD dwPermissions, __in ULONGLONG uSize, __in time_t dtModified,
00044         __in BOOL fIsFolder, __deref_out PITEMID_CHILD *ppidlOut )
00045 {
00046         ATLASSERT(sizeof(REMOTEPIDL) % sizeof(DWORD) == 0); // DWORD-aligned
00047 
00048         PITEMID_CHILD pidl = NULL;
00049 
00050         // Allocate enough memory to hold a REMOTEPIDL structure plus terminator
00051     pidl = (PITEMID_CHILD)CoTaskMemAlloc(sizeof(REMOTEPIDL) + sizeof(USHORT));
00052     if(!pidl)
00053                 return E_OUTOFMEMORY;
00054 
00055         // Use first PIDL member as a REMOTEPIDL structure
00056         PREMOTEPIDL pidlRemote = (PREMOTEPIDL)pidl;
00057 
00058         // Fill members of the PIDL with data
00059         pidlRemote->cb = sizeof REMOTEPIDL;
00060         pidlRemote->dwFingerprint = REMOTEPIDL_FINGERPRINT; // Sign with fingerprint
00061         CopyWSZString(pidlRemote->wszPath, 
00062                 ARRAYSIZE(pidlRemote->wszPath), pwszPath);
00063         CopyWSZString(pidlRemote->wszOwner, 
00064                 ARRAYSIZE(pidlRemote->wszOwner), pwszOwner);
00065         CopyWSZString(pidlRemote->wszGroup, 
00066                 ARRAYSIZE(pidlRemote->wszGroup), pwszGroup);
00067         pidlRemote->dwPermissions = dwPermissions;
00068         pidlRemote->uSize = uSize;
00069         pidlRemote->dtModified = dtModified;
00070         pidlRemote->fIsFolder = fIsFolder;
00071 
00072         // Create the terminating null PIDL by setting cb field to 0.
00073         LPITEMIDLIST pidlNext = GetNextItem(pidl);
00074         ATLASSERT(pidlNext != NULL);
00075         pidlNext->mkid.cb = 0;
00076 
00077         *ppidlOut = pidl;
00078         ATLASSERT(SUCCEEDED(IsValid(*ppidlOut)));
00079         ATLASSERT(ILGetNext(ILGetNext(*ppidlOut)) == NULL); // PIDL is terminated
00080         ATLASSERT(ILGetSize(*ppidlOut) == sizeof(REMOTEPIDL) + sizeof(USHORT));
00081 
00082     return S_OK;
00083 }
00084 
00114 PREMOTEPIDL CRemotePidlManager::Validate( PCIDLIST_RELATIVE pidl )
00115 {
00116         PREMOTEPIDL pRemotePidl = NULL;
00117 
00118     if (pidl)
00119     {
00120         pRemotePidl = (PREMOTEPIDL)pidl;
00121                 if (pRemotePidl->cb == sizeof(REMOTEPIDL_FINGERPRINT) && 
00122                         pRemotePidl->dwFingerprint == REMOTEPIDL_FINGERPRINT)
00123                         return pRemotePidl; // equivalent to true
00124         }
00125 
00126     return NULL; // equal to false
00127 }
00128 
00143 HRESULT CRemotePidlManager::IsValid( PCIDLIST_RELATIVE pidl )
00144 {
00145     PREMOTEPIDL pRemotePidl = Validate(pidl);
00146     return pRemotePidl ? S_OK : E_INVALIDARG;
00147 }
00148 
00160 CString CRemotePidlManager::GetPath( LPCITEMIDLIST pidl )
00161 {
00162         if (pidl == NULL) return _T("");
00163 
00164         return GetDataSegment(pidl)->wszPath;
00165 }
00166 
00178 CString CRemotePidlManager::GetOwner( LPCITEMIDLIST pidl )
00179 {
00180         if (pidl == NULL) return _T("");
00181 
00182         return GetDataSegment(pidl)->wszOwner;
00183 }
00184 
00196 CString CRemotePidlManager::GetGroup( LPCITEMIDLIST pidl )
00197 {
00198         if (pidl == NULL) return _T("");
00199 
00200         return GetDataSegment(pidl)->wszGroup;
00201 }
00202 
00214 DWORD CRemotePidlManager::GetPermissions( LPCITEMIDLIST pidl )
00215 {
00216         if (pidl == NULL) return 0;
00217 
00218         return GetDataSegment(pidl)->dwPermissions;
00219 }
00220 
00236 CString CRemotePidlManager::GetPermissionsStr( LPCITEMIDLIST pidl )
00237 {
00238         if (pidl == NULL) return _T("");
00239 
00240         // TODO: call old permissions function from swish prototype
00241         return _T("todo");
00242 }
00243 
00255 ULONGLONG CRemotePidlManager::GetFileSize( LPCITEMIDLIST pidl )
00256 {
00257         if (pidl == NULL) return 0;
00258 
00259         return GetDataSegment(pidl)->uSize;
00260 }
00261 
00273 CTime CRemotePidlManager::GetLastModified( LPCITEMIDLIST pidl )
00274 {
00275         if (pidl == NULL) return 0;
00276 
00277         return GetDataSegment(pidl)->dtModified;
00278 }
00279 
00291 BOOL CRemotePidlManager::IsFolder( LPCITEMIDLIST pidl )
00292 {
00293         if (pidl == NULL) return 0;
00294 
00295         return GetDataSegment(pidl)->fIsFolder;
00296 }
00297 
00309 PREMOTEPIDL CRemotePidlManager::GetDataSegment( LPCITEMIDLIST pidl )
00310 {
00311     // Get the last item of the PIDL to make sure we get the right value
00312     // in case of multiple nesting levels
00313         PITEMID_CHILD pidlRemote = CPidlManager::GetDataSegment( pidl );
00314 
00315         ATLASSERT(SUCCEEDED(IsValid( pidlRemote )));
00316         // If not, this is unexpected behviour. Why were we passed this PIDL?
00317 
00318         return Validate( pidlRemote );
00319 }

Generated on Mon Nov 12 22:43:54 2007 for Swish by  doxygen 1.5.3