VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecWin.cpp@ 49482

Last change on this file since 49482 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.9 KB
Line 
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38// This file is included by nsFileSpec.cp, and includes the Windows-specific
39// implementations.
40
41#include <sys/stat.h>
42#include <direct.h>
43#include <limits.h>
44#include <stdlib.h>
45#include "prio.h"
46#include "nsError.h"
47
48#include <windows.h>
49
50#if (_MSC_VER == 1100) || defined(__GNUC__)
51#define INITGUID
52#include <objbase.h>
53DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0);
54#endif
55
56#include <shlobj.h>
57#include <shellapi.h>
58#include <shlguid.h>
59
60#ifdef UNICODE
61#define CreateDirectoryW CreateDirectory
62#else
63#define CreateDirectoryA CreateDirectory
64#endif
65
66//----------------------------------------------------------------------------------------
67void nsFileSpecHelpers::Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs)
68// Canonify, make absolute, and check whether directories exist. This
69// takes a (possibly relative) native path and converts it into a
70// fully qualified native path.
71//----------------------------------------------------------------------------------------
72{
73 if (ioPath.IsEmpty())
74 return;
75
76 NS_ASSERTION(strchr((const char*)ioPath, '/') == 0,
77 "This smells like a Unix path. Native path expected! "
78 "Please fix.");
79 if (inMakeDirs)
80 {
81 const int mode = 0755;
82 nsSimpleCharString unixStylePath = ioPath;
83 nsFileSpecHelpers::NativeToUnix(unixStylePath);
84 nsFileSpecHelpers::MakeAllDirectories((const char*)unixStylePath, mode);
85 }
86 char buffer[_MAX_PATH];
87 errno = 0;
88 *buffer = '\0';
89 char* canonicalPath = _fullpath(buffer, ioPath, _MAX_PATH);
90
91 if (canonicalPath)
92 {
93 NS_ASSERTION( canonicalPath[0] != '\0', "Uh oh...couldn't convert" );
94 if (canonicalPath[0] == '\0')
95 return;
96 }
97 ioPath = canonicalPath;
98} // nsFileSpecHelpers::Canonify
99
100//----------------------------------------------------------------------------------------
101void nsFileSpecHelpers::UnixToNative(nsSimpleCharString& ioPath)
102// This just does string manipulation. It doesn't check reality, or canonify, or
103// anything
104//----------------------------------------------------------------------------------------
105{
106 // Allow for relative or absolute. We can do this in place, because the
107 // native path is never longer.
108
109 if (ioPath.IsEmpty())
110 return;
111
112 // Strip initial slash for an absolute path
113 char* src = (char*)ioPath;
114 if (*src == '/') {
115 if (!src[1]) {
116 // allocate new string by copying from ioPath[1]
117 nsSimpleCharString temp = src + 1;
118 ioPath = temp;
119 return;
120 }
121 // Since it was an absolute path, check for the drive letter
122 char* colonPointer = src + 2;
123 if (strstr(src, "|/") == colonPointer)
124 *colonPointer = ':';
125 // allocate new string by copying from ioPath[1]
126 nsSimpleCharString temp = src + 1;
127 ioPath = temp;
128 }
129
130 // Convert '/' to '\'. (Must check EVERY character: consider UNC path
131 // case.)
132 for (src = (char*)ioPath; *src; ++src)
133 {
134 if (*src == '/')
135 *src = '\\';
136 }
137
138} // nsFileSpecHelpers::UnixToNative
139
140//----------------------------------------------------------------------------------------
141void nsFileSpecHelpers::NativeToUnix(nsSimpleCharString& ioPath)
142// This just does string manipulation. It doesn't check reality, or canonify, or
143// anything. The unix path is longer, so we can't do it in place.
144//----------------------------------------------------------------------------------------
145{
146 if (ioPath.IsEmpty())
147 return;
148
149 // Convert the drive-letter separator, if present
150 nsSimpleCharString temp("/");
151
152 char* cp = (char*)ioPath + 1;
153 if (strstr(cp, ":\\") == cp)
154 *cp = '|'; // absolute path
155 else
156 if (cp[0] == '\\') // unc path
157 cp--;
158 else
159 temp[0] = '\0'; // relative path
160
161 // Convert '\' to '/'
162 for (; *cp; cp++)
163 {
164 if(IsDBCSLeadByte(*cp) && *(cp+1) != nsnull)
165 {
166 cp++;
167 continue;
168 }
169 if (*cp == '\\')
170 *cp = '/';
171 }
172 // Add the slash in front.
173 temp += ioPath;
174 ioPath = temp;
175}
176
177//----------------------------------------------------------------------------------------
178nsFileSpec::nsFileSpec(const nsFilePath& inPath)
179//----------------------------------------------------------------------------------------
180{
181// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
182 *this = inPath;
183}
184
185//----------------------------------------------------------------------------------------
186void nsFileSpec::operator = (const nsFilePath& inPath)
187//----------------------------------------------------------------------------------------
188{
189 mPath = (const char*)inPath;
190 nsFileSpecHelpers::UnixToNative(mPath);
191 mError = NS_OK;
192} // nsFileSpec::operator =
193
194//----------------------------------------------------------------------------------------
195nsFilePath::nsFilePath(const nsFileSpec& inSpec)
196//----------------------------------------------------------------------------------------
197{
198 *this = inSpec;
199} // nsFilePath::nsFilePath
200
201//----------------------------------------------------------------------------------------
202void nsFilePath::operator = (const nsFileSpec& inSpec)
203//----------------------------------------------------------------------------------------
204{
205 mPath = inSpec.mPath;
206 nsFileSpecHelpers::NativeToUnix(mPath);
207} // nsFilePath::operator =
208
209//----------------------------------------------------------------------------------------
210void nsFileSpec::SetLeafName(const char* inLeafName)
211//----------------------------------------------------------------------------------------
212{
213 NS_ASSERTION(inLeafName, "Attempt to SetLeafName with a null string");
214 mPath.LeafReplace('\\', inLeafName);
215} // nsFileSpec::SetLeafName
216
217//----------------------------------------------------------------------------------------
218char* nsFileSpec::GetLeafName() const
219//----------------------------------------------------------------------------------------
220{
221 return mPath.GetLeaf('\\');
222} // nsFileSpec::GetLeafName
223
224//----------------------------------------------------------------------------------------
225PRBool nsFileSpec::Exists() const
226//----------------------------------------------------------------------------------------
227{
228 struct stat st;
229 return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st);
230} // nsFileSpec::Exists
231
232//----------------------------------------------------------------------------------------
233void nsFileSpec::GetModDate(TimeStamp& outStamp) const
234//----------------------------------------------------------------------------------------
235{
236 struct stat st;
237 if (!mPath.IsEmpty() && stat(nsNSPRPath(*this), &st) == 0)
238 outStamp = st.st_mtime;
239 else
240 outStamp = 0;
241} // nsFileSpec::GetModDate
242
243//----------------------------------------------------------------------------------------
244PRUint32 nsFileSpec::GetFileSize() const
245//----------------------------------------------------------------------------------------
246{
247 struct stat st;
248 if (!mPath.IsEmpty() && stat(nsNSPRPath(*this), &st) == 0)
249 return (PRUint32)st.st_size;
250 return 0;
251} // nsFileSpec::GetFileSize
252
253//----------------------------------------------------------------------------------------
254PRBool nsFileSpec::IsFile() const
255//----------------------------------------------------------------------------------------
256{
257 struct stat st;
258 return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && (_S_IFREG & st.st_mode);
259} // nsFileSpec::IsFile
260
261//----------------------------------------------------------------------------------------
262PRBool nsFileSpec::IsDirectory() const
263//----------------------------------------------------------------------------------------
264{
265 struct stat st;
266 return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && (_S_IFDIR & st.st_mode);
267} // nsFileSpec::IsDirectory
268
269//----------------------------------------------------------------------------------------
270PRBool nsFileSpec::IsHidden() const
271//----------------------------------------------------------------------------------------
272{
273 PRBool hidden = PR_FALSE;
274 if (!mPath.IsEmpty())
275 {
276 DWORD attr = GetFileAttributes(mPath);
277 if (FILE_ATTRIBUTE_HIDDEN & attr)
278 hidden = PR_TRUE;
279 }
280 return hidden;
281}
282// nsFileSpec::IsHidden
283
284//----------------------------------------------------------------------------------------
285PRBool nsFileSpec::IsSymlink() const
286//----------------------------------------------------------------------------------------
287{
288 HRESULT hres;
289 IShellLink* psl;
290
291 PRBool isSymlink = PR_FALSE;
292
293 CoInitialize(NULL);
294 // Get a pointer to the IShellLink interface.
295 hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
296 if (SUCCEEDED(hres))
297 {
298 IPersistFile* ppf;
299
300 // Get a pointer to the IPersistFile interface.
301 hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
302
303 if (SUCCEEDED(hres))
304 {
305 WCHAR wsz[MAX_PATH];
306 // Ensure that the string is Unicode.
307 MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
308
309 // Load the shortcut.
310 hres = ppf->Load(wsz, STGM_READ);
311 if (SUCCEEDED(hres))
312 {
313 isSymlink = PR_TRUE;
314 }
315
316 // Release the pointer to the IPersistFile interface.
317 ppf->Release();
318 }
319
320 // Release the pointer to the IShellLink interface.
321 psl->Release();
322 }
323
324 CoUninitialize();
325
326 return isSymlink;
327}
328
329
330//----------------------------------------------------------------------------------------
331nsresult nsFileSpec::ResolveSymlink(PRBool& wasSymlink)
332//----------------------------------------------------------------------------------------
333{
334 wasSymlink = PR_FALSE; // assume failure
335
336 if (Exists())
337 return NS_OK;
338
339
340 HRESULT hres;
341 IShellLink* psl;
342
343 CoInitialize(NULL);
344
345 // Get a pointer to the IShellLink interface.
346 hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
347 if (SUCCEEDED(hres))
348 {
349 IPersistFile* ppf;
350
351 // Get a pointer to the IPersistFile interface.
352 hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
353
354 if (SUCCEEDED(hres))
355 {
356 WCHAR wsz[MAX_PATH];
357 // Ensure that the string is Unicode.
358 MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
359
360 // Load the shortcut.
361 hres = ppf->Load(wsz, STGM_READ);
362 if (SUCCEEDED(hres))
363 {
364 wasSymlink = PR_TRUE;
365
366 // Resolve the link.
367 hres = psl->Resolve(nsnull, SLR_NO_UI );
368 if (SUCCEEDED(hres))
369 {
370 char szGotPath[MAX_PATH];
371 WIN32_FIND_DATA wfd;
372
373 // Get the path to the link target.
374 hres = psl->GetPath( szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY );
375
376 if (SUCCEEDED(hres))
377 {
378 // Here we modify the nsFileSpec;
379 mPath = szGotPath;
380 mError = NS_OK;
381 }
382 }
383 }
384 else {
385 // It wasn't a shortcut. Oh well. Leave it like it was.
386 hres = 0;
387 }
388
389 // Release the pointer to the IPersistFile interface.
390 ppf->Release();
391 }
392 // Release the pointer to the IShellLink interface.
393 psl->Release();
394 }
395
396 CoUninitialize();
397
398 if (SUCCEEDED(hres))
399 return NS_OK;
400
401 return NS_FILE_FAILURE;
402}
403
404
405
406//----------------------------------------------------------------------------------------
407void nsFileSpec::GetParent(nsFileSpec& outSpec) const
408//----------------------------------------------------------------------------------------
409{
410 outSpec.mPath = mPath;
411 char* chars = (char*)outSpec.mPath;
412 chars[outSpec.mPath.Length() - 1] = '\0'; // avoid trailing separator, if any
413 char* cp = strrchr(chars, '\\');
414 if (cp++)
415 outSpec.mPath.SetLength(cp - chars); // truncate.
416} // nsFileSpec::GetParent
417
418//----------------------------------------------------------------------------------------
419void nsFileSpec::operator += (const char* inRelativePath)
420//----------------------------------------------------------------------------------------
421{
422 NS_ASSERTION(inRelativePath, "Attempt to do += with a null string");
423
424 if (!inRelativePath || mPath.IsEmpty())
425 return;
426
427 if (mPath[mPath.Length() - 1] == '\\')
428 mPath += "x";
429 else
430 mPath += "\\x";
431
432 // If it's a (unix) relative path, make it native
433 nsSimpleCharString dosPath = inRelativePath;
434 nsFileSpecHelpers::UnixToNative(dosPath);
435 SetLeafName(dosPath);
436} // nsFileSpec::operator +=
437
438//----------------------------------------------------------------------------------------
439void nsFileSpec::CreateDirectory(int /*mode*/)
440//----------------------------------------------------------------------------------------
441{
442 // Note that mPath is canonical!
443 if (!mPath.IsEmpty())
444 mkdir(nsNSPRPath(*this));
445} // nsFileSpec::CreateDirectory
446
447//----------------------------------------------------------------------------------------
448void nsFileSpec::Delete(PRBool inRecursive) const
449//----------------------------------------------------------------------------------------
450{
451 if (IsDirectory())
452 {
453 if (inRecursive)
454 {
455 for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
456 {
457 nsFileSpec& child = (nsFileSpec&)i;
458 child.Delete(inRecursive);
459 }
460 }
461 rmdir(nsNSPRPath(*this));
462 }
463 else if (!mPath.IsEmpty())
464 {
465 remove(nsNSPRPath(*this));
466 }
467} // nsFileSpec::Delete
468
469
470//----------------------------------------------------------------------------------------
471void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
472//----------------------------------------------------------------------------------------
473{
474 if (IsDirectory())
475 {
476 if (!(newDir.Exists()))
477 {
478 newDir.CreateDirectory();
479 }
480
481 for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
482 {
483 nsFileSpec& child = (nsFileSpec&)i;
484
485 if (child.IsDirectory())
486 {
487 nsFileSpec tmpDirSpec(newDir);
488
489 char *leafname = child.GetLeafName();
490 tmpDirSpec += leafname;
491 nsCRT::free(leafname);
492
493 child.RecursiveCopy(tmpDirSpec);
494 }
495 else
496 {
497 child.RecursiveCopy(newDir);
498 }
499 }
500 }
501 else if (!mPath.IsEmpty())
502 {
503 nsFileSpec& filePath = (nsFileSpec&) *this;
504
505 if (!(newDir.Exists()))
506 {
507 newDir.CreateDirectory();
508 }
509
510 filePath.CopyToDir(newDir);
511 }
512} // nsFileSpec::RecursiveCopy
513
514//----------------------------------------------------------------------------------------
515nsresult
516nsFileSpec::Truncate(PRInt32 aNewFileLength) const
517//----------------------------------------------------------------------------------------
518{
519 DWORD status;
520 HANDLE hFile;
521
522 // Leave it to Microsoft to open an existing file with a function
523 // named "CreateFile".
524 hFile = CreateFile(mPath,
525 GENERIC_WRITE,
526 FILE_SHARE_READ,
527 NULL,
528 OPEN_EXISTING,
529 FILE_ATTRIBUTE_NORMAL,
530 NULL);
531 if (hFile == INVALID_HANDLE_VALUE)
532 return NS_FILE_FAILURE;
533
534 // Seek to new, desired end of file
535 status = SetFilePointer(hFile, aNewFileLength, NULL, FILE_BEGIN);
536 if (status == 0xffffffff)
537 goto error;
538
539 // Truncate file at current cursor position
540 if (!SetEndOfFile(hFile))
541 goto error;
542
543 if (!CloseHandle(hFile))
544 return NS_FILE_FAILURE;
545
546 return NS_OK;
547
548 error:
549 CloseHandle(hFile);
550 return NS_FILE_FAILURE;
551
552} // nsFileSpec::Truncate
553
554//----------------------------------------------------------------------------------------
555nsresult nsFileSpec::Rename(const char* inNewName)
556//----------------------------------------------------------------------------------------
557{
558 NS_ASSERTION(inNewName, "Attempt to Rename with a null string");
559
560 // This function should not be used to move a file on disk.
561 if (strchr(inNewName, '/'))
562 return NS_FILE_FAILURE;
563
564 char* oldPath = nsCRT::strdup(mPath);
565
566 SetLeafName(inNewName);
567
568 if (PR_Rename(oldPath, mPath) != NS_OK)
569 {
570 // Could not rename, set back to the original.
571 mPath = oldPath;
572 return NS_FILE_FAILURE;
573 }
574
575 nsCRT::free(oldPath);
576
577 return NS_OK;
578} // nsFileSpec::Rename
579
580//----------------------------------------------------------------------------------------
581nsresult nsFileSpec::CopyToDir(const nsFileSpec& inParentDirectory) const
582//----------------------------------------------------------------------------------------
583{
584 // We can only copy into a directory, and (for now) can not copy entire directories
585 if (inParentDirectory.IsDirectory() && (! IsDirectory() ) )
586 {
587 char *leafname = GetLeafName();
588 nsSimpleCharString destPath(inParentDirectory.GetCString());
589 destPath += "\\";
590 destPath += leafname;
591 nsCRT::free(leafname);
592
593 // CopyFile returns non-zero if succeeds
594 int copyOK = CopyFile(GetCString(), destPath, PR_TRUE);
595 if (copyOK)
596 return NS_OK;
597 }
598 return NS_FILE_FAILURE;
599} // nsFileSpec::CopyToDir
600
601//----------------------------------------------------------------------------------------
602nsresult nsFileSpec::MoveToDir(const nsFileSpec& inNewParentDirectory)
603//----------------------------------------------------------------------------------------
604{
605 // We can only copy into a directory, and (for now) can not copy entire directories
606 if (inNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
607 {
608 char *leafname = GetLeafName();
609 nsSimpleCharString destPath(inNewParentDirectory.GetCString());
610 destPath += "\\";
611 destPath += leafname;
612 nsCRT::free(leafname);
613
614 // MoveFile returns non-zero if succeeds
615 int copyOK = MoveFile(GetCString(), destPath);
616
617 if (copyOK)
618 {
619 *this = inNewParentDirectory + GetLeafName();
620 return NS_OK;
621 }
622
623 }
624 return NS_FILE_FAILURE;
625} // nsFileSpec::MoveToDir
626
627//----------------------------------------------------------------------------------------
628nsresult nsFileSpec::Execute(const char* inArgs ) const
629//----------------------------------------------------------------------------------------
630{
631 if (!IsDirectory())
632 {
633 nsSimpleCharString fileNameWithArgs = "\"";
634 fileNameWithArgs += mPath + "\" " + inArgs;
635 int execResult = WinExec( fileNameWithArgs, SW_NORMAL );
636 if (execResult > 31)
637 return NS_OK;
638 }
639 return NS_FILE_FAILURE;
640} // nsFileSpec::Execute
641
642
643//----------------------------------------------------------------------------------------
644PRInt64 nsFileSpec::GetDiskSpaceAvailable() const
645//----------------------------------------------------------------------------------------
646{
647 PRInt64 int64;
648
649 LL_I2L(int64 , LONG_MAX);
650
651 char aDrive[_MAX_DRIVE + 2];
652 _splitpath( (const char*)mPath, aDrive, NULL, NULL, NULL);
653
654 if (aDrive[0] == '\0')
655 {
656 // The back end is always trying to pass us paths that look
657 // like /c|/netscape/mail. See if we've got one of them
658 if (mPath.Length() > 2 && mPath[0] == '/' && mPath[2] == '|')
659 {
660 aDrive[0] = mPath[1];
661 aDrive[1] = ':';
662 aDrive[2] = '\0';
663 }
664 else
665 {
666 // Return bogus large number and hope for the best
667 return int64;
668 }
669 }
670
671 strcat(aDrive, "\\");
672
673 // Check disk space
674 DWORD dwSecPerClus, dwBytesPerSec, dwFreeClus, dwTotalClus;
675 ULARGE_INTEGER liFreeBytesAvailableToCaller, liTotalNumberOfBytes, liTotalNumberOfFreeBytes;
676 double nBytes = 0;
677
678 BOOL (WINAPI* getDiskFreeSpaceExA)(LPCTSTR lpDirectoryName,
679 PULARGE_INTEGER lpFreeBytesAvailableToCaller,
680 PULARGE_INTEGER lpTotalNumberOfBytes,
681 PULARGE_INTEGER lpTotalNumberOfFreeBytes) = NULL;
682
683 HINSTANCE hInst = LoadLibrary("KERNEL32.DLL");
684 NS_ASSERTION(hInst != NULL, "COULD NOT LOAD KERNEL32.DLL");
685 if (hInst != NULL)
686 {
687 getDiskFreeSpaceExA = (BOOL (WINAPI*)(LPCTSTR lpDirectoryName,
688 PULARGE_INTEGER lpFreeBytesAvailableToCaller,
689 PULARGE_INTEGER lpTotalNumberOfBytes,
690 PULARGE_INTEGER lpTotalNumberOfFreeBytes))
691 GetProcAddress(hInst, "GetDiskFreeSpaceExA");
692 FreeLibrary(hInst);
693 }
694
695 if (getDiskFreeSpaceExA && (*getDiskFreeSpaceExA)(aDrive,
696 &liFreeBytesAvailableToCaller,
697 &liTotalNumberOfBytes,
698 &liTotalNumberOfFreeBytes))
699 {
700 nBytes = (double)(signed __int64)liFreeBytesAvailableToCaller.QuadPart;
701 }
702 else if ( GetDiskFreeSpace(aDrive, &dwSecPerClus, &dwBytesPerSec, &dwFreeClus, &dwTotalClus))
703 {
704 nBytes = (double)dwFreeClus*(double)dwSecPerClus*(double) dwBytesPerSec;
705 }
706 return (PRInt64)nBytes;
707}
708
709
710
711//========================================================================================
712// nsDirectoryIterator
713//========================================================================================
714
715//----------------------------------------------------------------------------------------
716nsDirectoryIterator::nsDirectoryIterator(const nsFileSpec& inDirectory, PRBool resolveSymlink)
717//----------------------------------------------------------------------------------------
718 : mCurrent(inDirectory)
719 , mDir(nsnull)
720 , mStarting(inDirectory)
721 , mExists(PR_FALSE)
722 , mResoveSymLinks(resolveSymlink)
723{
724 mDir = PR_OpenDir(inDirectory);
725 mCurrent += "dummy";
726 mStarting += "dummy";
727 ++(*this);
728} // nsDirectoryIterator::nsDirectoryIterator
729
730//----------------------------------------------------------------------------------------
731nsDirectoryIterator::~nsDirectoryIterator()
732//----------------------------------------------------------------------------------------
733{
734 if (mDir)
735 PR_CloseDir(mDir);
736} // nsDirectoryIterator::nsDirectoryIterator
737
738//----------------------------------------------------------------------------------------
739nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
740//----------------------------------------------------------------------------------------
741{
742 mExists = PR_FALSE;
743 if (!mDir)
744 return *this;
745 PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH); // Ignore '.' && '..'
746 if (entry)
747 {
748 mExists = PR_TRUE;
749 mCurrent = mStarting;
750 mCurrent.SetLeafName(entry->name);
751 if (mResoveSymLinks)
752 {
753 PRBool ignore;
754 mCurrent.ResolveSymlink(ignore);
755 }
756 }
757 return *this;
758} // nsDirectoryIterator::operator ++
759
760//----------------------------------------------------------------------------------------
761nsDirectoryIterator& nsDirectoryIterator::operator -- ()
762//----------------------------------------------------------------------------------------
763{
764 return ++(*this); // can't do it backwards.
765} // nsDirectoryIterator::operator --
766
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette