VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/io/nsLocalFileOS2.cpp@ 31232

最後變更 在這個檔案從31232是 1,由 vboxsync 提交於 55 年 前

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 41.6 KB
 
1/* -*- Mode: C++; tab-width: 4; 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 Communicator client code, released
16 * March 31, 1998.
17 *
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998-2000
21 * the Initial Developer. All Rights Reserved.
22 *
23 * Contributor(s):
24 * Henry Sobotka <[email protected]>
25 * IBM Corp.
26 *
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
38 *
39 * ***** END LICENSE BLOCK ***** */
40
41
42#include "nsCOMPtr.h"
43#include "nsMemory.h"
44
45#include "nsLocalFile.h"
46#include "nsNativeCharsetUtils.h"
47
48#include "nsISimpleEnumerator.h"
49#include "nsIComponentManager.h"
50#include "prtypes.h"
51#include "prio.h"
52
53#include <ctype.h> // needed for toupper
54#include <string.h>
55
56#include "nsXPIDLString.h"
57#include "nsReadableUtils.h"
58#include "prproces.h"
59#include "prthread.h"
60
61
62static unsigned char* PR_CALLBACK
63_mbschr( const unsigned char* stringToSearch, int charToSearchFor);
64extern unsigned char*
65_mbsrchr( const unsigned char* stringToSearch, int charToSearchFor);
66static nsresult PR_CALLBACK
67CreateDirectoryA( PSZ path, PEAOP2 ppEABuf);
68static int isleadbyte(int c);
69
70#include <unistd.h>
71#include <io.h>
72
73
74static nsresult ConvertOS2Error(int err)
75{
76 nsresult rv;
77
78 switch (err)
79 {
80 case ERROR_FILE_NOT_FOUND:
81 case ERROR_PATH_NOT_FOUND:
82 case ERROR_INVALID_DRIVE:
83 rv = NS_ERROR_FILE_NOT_FOUND;
84 break;
85 case ERROR_ACCESS_DENIED:
86 case ERROR_NOT_SAME_DEVICE:
87 rv = NS_ERROR_FILE_ACCESS_DENIED;
88 break;
89 case ERROR_NOT_ENOUGH_MEMORY:
90 case ERROR_INVALID_BLOCK:
91 case ERROR_INVALID_HANDLE:
92 case ERROR_ARENA_TRASHED:
93 rv = NS_ERROR_OUT_OF_MEMORY;
94 break;
95 case ERROR_CURRENT_DIRECTORY:
96 rv = NS_ERROR_FILE_DIR_NOT_EMPTY;
97 break;
98 case ERROR_WRITE_PROTECT:
99 rv = NS_ERROR_FILE_READ_ONLY;
100 break;
101 case ERROR_HANDLE_DISK_FULL:
102 rv = NS_ERROR_FILE_TOO_BIG;
103 break;
104 case ERROR_FILE_EXISTS:
105 case ERROR_ALREADY_EXISTS:
106 case ERROR_CANNOT_MAKE:
107 rv = NS_ERROR_FILE_ALREADY_EXISTS;
108 break;
109 case 0:
110 rv = NS_OK;
111 default:
112 rv = NS_ERROR_FAILURE;
113 }
114 return rv;
115}
116
117static void
118myLL_L2II(PRInt64 result, PRInt32 *hi, PRInt32 *lo )
119{
120 PRInt64 a64, b64; // probably could have been done with
121 // only one PRInt64, but these are macros,
122 // and I am a wimp.
123
124 // shift the hi word to the low word, then push it into a long.
125 LL_SHR(a64, result, 32);
126 LL_L2I(*hi, a64);
127
128 // shift the low word to the hi word first, then shift it back.
129 LL_SHL(b64, result, 32);
130 LL_SHR(a64, b64, 32);
131 LL_L2I(*lo, a64);
132}
133
134
135class nsDirEnumerator : public nsISimpleEnumerator
136{
137 public:
138
139 NS_DECL_ISUPPORTS
140
141 nsDirEnumerator() : mDir(nsnull)
142 {
143 }
144
145 nsresult Init(nsILocalFile* parent)
146 {
147 nsCAutoString filepath;
148 parent->GetNativeTarget(filepath);
149
150 if (filepath.IsEmpty())
151 {
152 parent->GetNativePath(filepath);
153 }
154
155 if (filepath.IsEmpty())
156 {
157 return NS_ERROR_UNEXPECTED;
158 }
159
160 mDir = PR_OpenDir(filepath.get());
161 if (mDir == nsnull) // not a directory?
162 return NS_ERROR_FAILURE;
163
164 mParent = parent;
165 return NS_OK;
166 }
167
168 NS_IMETHOD HasMoreElements(PRBool *result)
169 {
170 nsresult rv;
171 if (mNext == nsnull && mDir)
172 {
173 PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH);
174 if (entry == nsnull)
175 {
176 // end of dir entries
177
178 PRStatus status = PR_CloseDir(mDir);
179 if (status != PR_SUCCESS)
180 return NS_ERROR_FAILURE;
181 mDir = nsnull;
182
183 *result = PR_FALSE;
184 return NS_OK;
185 }
186
187 nsCOMPtr<nsIFile> file;
188 rv = mParent->Clone(getter_AddRefs(file));
189 if (NS_FAILED(rv))
190 return rv;
191
192 rv = file->AppendNative(nsDependentCString(entry->name));
193 if (NS_FAILED(rv))
194 return rv;
195
196 // make sure the thing exists. If it does, try the next one.
197 PRBool exists;
198 rv = file->Exists(&exists);
199 if (NS_FAILED(rv) || !exists)
200 {
201 return HasMoreElements(result);
202 }
203
204 mNext = do_QueryInterface(file);
205 }
206 *result = mNext != nsnull;
207 return NS_OK;
208 }
209
210 NS_IMETHOD GetNext(nsISupports **result)
211 {
212 nsresult rv;
213 PRBool hasMore;
214 rv = HasMoreElements(&hasMore);
215 if (NS_FAILED(rv)) return rv;
216
217 *result = mNext; // might return nsnull
218 NS_IF_ADDREF(*result);
219
220 mNext = nsnull;
221 return NS_OK;
222 }
223
224 private:
225 ~nsDirEnumerator()
226 {
227 if (mDir)
228 {
229 PRStatus status = PR_CloseDir(mDir);
230 NS_ASSERTION(status == PR_SUCCESS, "close failed");
231 }
232 }
233
234 protected:
235 PRDir* mDir;
236 nsCOMPtr<nsILocalFile> mParent;
237 nsCOMPtr<nsILocalFile> mNext;
238};
239
240NS_IMPL_ISUPPORTS1(nsDirEnumerator, nsISimpleEnumerator)
241
242
243nsLocalFile::nsLocalFile()
244{
245 MakeDirty();
246}
247
248nsLocalFile::nsLocalFile(const nsLocalFile& other)
249 : mDirty(other.mDirty)
250 , mWorkingPath(other.mWorkingPath)
251 , mFileInfo64(other.mFileInfo64)
252{
253}
254
255/* nsISupports interface implementation. */
256NS_IMPL_THREADSAFE_ISUPPORTS2(nsLocalFile, nsILocalFile, nsIFile)
257
258NS_METHOD
259nsLocalFile::nsLocalFileConstructor(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
260{
261 NS_ENSURE_ARG_POINTER(aInstancePtr);
262 NS_ENSURE_NO_AGGREGATION(outer);
263
264 nsLocalFile* inst = new nsLocalFile();
265 if (inst == NULL)
266 return NS_ERROR_OUT_OF_MEMORY;
267
268 nsresult rv = inst->QueryInterface(aIID, aInstancePtr);
269 if (NS_FAILED(rv))
270 {
271 delete inst;
272 return rv;
273 }
274 return NS_OK;
275}
276
277// This function resets any cached information about the file.
278void
279nsLocalFile::MakeDirty()
280{
281 mDirty = PR_TRUE;
282}
283
284nsresult
285nsLocalFile::Stat()
286{
287 if (!mDirty)
288 return NS_OK;
289
290 char temp[4];
291 const char* workingFilePath = mWorkingPath.get();
292 const char* nsprPath = workingFilePath;
293
294 if (mWorkingPath.Length() == 2 && mWorkingPath.CharAt(1) == ':') {
295 temp[0] = workingFilePath[0];
296 temp[1] = workingFilePath[1];
297 temp[2] = '\\';
298 temp[3] = '\0';
299 nsprPath = temp;
300 }
301
302 DosError(FERR_DISABLEHARDERR);
303 PRStatus status = PR_GetFileInfo64(nsprPath, &mFileInfo64);
304 DosError(FERR_ENABLEHARDERR);
305 if ( status == PR_SUCCESS )
306 return NS_OK;
307
308 return NS_ERROR_FILE_NOT_FOUND;
309}
310
311NS_IMETHODIMP
312nsLocalFile::Clone(nsIFile **file)
313{
314 // Just copy-construct ourselves
315 *file = new nsLocalFile(*this);
316 if (!*file)
317 return NS_ERROR_OUT_OF_MEMORY;
318
319 NS_ADDREF(*file);
320
321 return NS_OK;
322}
323
324NS_IMETHODIMP
325nsLocalFile::InitWithNativePath(const nsACString &filePath)
326{
327 MakeDirty();
328
329 nsACString::const_iterator begin, end;
330 filePath.BeginReading(begin);
331 filePath.EndReading(end);
332
333 // input string must not be empty
334 if (begin == end)
335 return NS_ERROR_FAILURE;
336
337 char firstChar = *begin;
338 char secondChar = *(++begin);
339
340 // just do a sanity check. if it has any forward slashes, it is not a Native path
341 // on windows. Also, it must have a colon at after the first char.
342
343 char *path = nsnull;
344 PRInt32 pathLen = 0;
345
346 if ( ( (secondChar == ':') && !FindCharInReadable('/', begin, end) ) || // normal path
347 ( (firstChar == '\\') && (secondChar == '\\') ) ) // network path
348 {
349 // This is a native path
350 path = ToNewCString(filePath);
351 pathLen = filePath.Length();
352 }
353
354 if (path == nsnull)
355 return NS_ERROR_FILE_UNRECOGNIZED_PATH;
356
357 // kill any trailing '\' provided it isn't the second char of DBCS
358 PRInt32 len = pathLen - 1;
359 if (path[len] == '\\' && !::isleadbyte(path[len-1]))
360 {
361 path[len] = '\0';
362 pathLen = len;
363 }
364
365 mWorkingPath.Adopt(path, pathLen);
366 return NS_OK;
367}
368
369NS_IMETHODIMP
370nsLocalFile::OpenNSPRFileDesc(PRInt32 flags, PRInt32 mode, PRFileDesc **_retval)
371{
372 nsresult rv = Stat();
373 if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND)
374 return rv;
375
376 *_retval = PR_Open(mWorkingPath.get(), flags, mode);
377
378 if (*_retval)
379 return NS_OK;
380
381 return NS_ErrorAccordingToNSPR();
382}
383
384
385NS_IMETHODIMP
386nsLocalFile::OpenANSIFileDesc(const char *mode, FILE * *_retval)
387{
388 nsresult rv = Stat();
389 if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND)
390 return rv;
391
392 *_retval = fopen(mWorkingPath.get(), mode);
393
394 if (*_retval)
395 return NS_OK;
396
397 return NS_ERROR_FAILURE;
398}
399
400
401
402NS_IMETHODIMP
403nsLocalFile::Create(PRUint32 type, PRUint32 attributes)
404{
405 if (type != NORMAL_FILE_TYPE && type != DIRECTORY_TYPE)
406 return NS_ERROR_FILE_UNKNOWN_TYPE;
407
408 nsresult rv = Stat();
409 if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND)
410 return rv;
411
412 // create nested directories to target
413 unsigned char* slash = _mbschr((const unsigned char*) mWorkingPath.get(), '\\');
414
415
416 if (slash)
417 {
418 // skip the first '\\'
419 ++slash;
420 slash = _mbschr(slash, '\\');
421
422 while (slash)
423 {
424 *slash = '\0';
425
426 rv = CreateDirectoryA(NS_CONST_CAST(char*, mWorkingPath.get()), NULL);
427 if (rv) {
428 rv = ConvertOS2Error(rv);
429 if (rv != NS_ERROR_FILE_ALREADY_EXISTS) return rv;
430 }
431 *slash = '\\';
432 ++slash;
433 slash = _mbschr(slash, '\\');
434 }
435 }
436
437 if (type == NORMAL_FILE_TYPE)
438 {
439 PRFileDesc* file = PR_Open(mWorkingPath.get(), PR_RDONLY | PR_CREATE_FILE | PR_APPEND | PR_EXCL, attributes);
440 if (!file) return NS_ERROR_FILE_ALREADY_EXISTS;
441
442 PR_Close(file);
443 return NS_OK;
444 }
445
446 if (type == DIRECTORY_TYPE)
447 {
448 rv = CreateDirectoryA(NS_CONST_CAST(char*, mWorkingPath.get()), NULL);
449 if (rv)
450 return ConvertOS2Error(rv);
451 else
452 return NS_OK;
453 }
454
455 return NS_ERROR_FILE_UNKNOWN_TYPE;
456}
457
458NS_IMETHODIMP
459nsLocalFile::AppendNative(const nsACString &node)
460{
461 if (node.IsEmpty())
462 return NS_OK;
463
464 // Append only one component. Check for subdirs.
465 // XXX can we avoid the PromiseFlatCString call?
466 if (_mbschr((const unsigned char*) PromiseFlatCString(node).get(), '\\') != nsnull)
467 return NS_ERROR_FILE_UNRECOGNIZED_PATH;
468
469 return AppendRelativeNativePath(node);
470}
471
472NS_IMETHODIMP
473nsLocalFile::AppendRelativeNativePath(const nsACString &node)
474{
475 // Cannot start with a / or have .. or have / anywhere
476 nsACString::const_iterator begin, end;
477 node.BeginReading(begin);
478 node.EndReading(end);
479 if (node.IsEmpty() || FindCharInReadable('/', begin, end))
480 {
481 return NS_ERROR_FILE_UNRECOGNIZED_PATH;
482 }
483 MakeDirty();
484 mWorkingPath.Append(NS_LITERAL_CSTRING("\\") + node);
485 return NS_OK;
486}
487
488NS_IMETHODIMP
489nsLocalFile::Normalize()
490{
491 return NS_OK;
492}
493
494NS_IMETHODIMP
495nsLocalFile::GetNativeLeafName(nsACString &aLeafName)
496{
497 aLeafName.Truncate();
498
499 const char* temp = mWorkingPath.get();
500 if(temp == nsnull)
501 return NS_ERROR_FILE_UNRECOGNIZED_PATH;
502
503 const char* leaf = (const char*) _mbsrchr((const unsigned char*) temp, '\\');
504
505 // if the working path is just a node without any lashes.
506 if (leaf == nsnull)
507 leaf = temp;
508 else
509 leaf++;
510
511 aLeafName.Assign(leaf);
512 return NS_OK;
513}
514
515NS_IMETHODIMP
516nsLocalFile::SetNativeLeafName(const nsACString &aLeafName)
517{
518 MakeDirty();
519
520 const unsigned char* temp = (const unsigned char*) mWorkingPath.get();
521 if(temp == nsnull)
522 return NS_ERROR_FILE_UNRECOGNIZED_PATH;
523
524 // cannot use nsCString::RFindChar() due to 0x5c problem
525 PRInt32 offset = (PRInt32) (_mbsrchr(temp, '\\') - temp);
526 if (offset)
527 {
528 mWorkingPath.Truncate(offset+1);
529 }
530 mWorkingPath.Append(aLeafName);
531
532 return NS_OK;
533}
534
535
536NS_IMETHODIMP
537nsLocalFile::GetNativePath(nsACString &_retval)
538{
539 _retval = mWorkingPath;
540 return NS_OK;
541}
542
543nsresult
544nsLocalFile::CopySingleFile(nsIFile *sourceFile, nsIFile *destParent, const nsACString &newName, PRBool move)
545{
546 nsresult rv;
547 nsCAutoString filePath;
548
549 nsCAutoString destPath;
550 destParent->GetNativeTarget(destPath);
551
552 destPath.Append("\\");
553
554 if (newName.IsEmpty())
555 {
556 nsCAutoString aFileName;
557 sourceFile->GetNativeLeafName(aFileName);
558 destPath.Append(aFileName);
559 }
560 else
561 {
562 destPath.Append(newName);
563 }
564
565 rv = sourceFile->GetNativePath(filePath);
566
567 if (NS_FAILED(rv))
568 return rv;
569
570 APIRET rc = NO_ERROR;
571
572 if( move )
573 {
574 rc = DosMove(filePath.get(), (PSZ)NS_CONST_CAST(char*, destPath.get()));
575 }
576
577 if (!move || rc == ERROR_NOT_SAME_DEVICE || rc == ERROR_ACCESS_DENIED) {
578 /* will get an error if the destination and source files aren't on the
579 * same drive. "MoveFile()" on Windows will go ahead and move the
580 * file without error, so we need to do the same IBM-AKR
581 */
582 do {
583 rc = DosCopy(filePath.get(), (PSZ)NS_CONST_CAST(char*, destPath.get()), DCPY_EXISTING);
584 if (rc == ERROR_TOO_MANY_OPEN_FILES) {
585 ULONG CurMaxFH = 0;
586 LONG ReqCount = 20;
587 APIRET rc2;
588 rc2 = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
589 if (rc2 != NO_ERROR) {
590 break;
591 }
592 }
593 } while (rc == ERROR_TOO_MANY_OPEN_FILES);
594
595 /* WSOD2 HACK */
596 if (rc == 65) { // NETWORK_ACCESS_DENIED
597 CHAR achProgram[CCHMAXPATH]; // buffer for program name, parameters
598 RESULTCODES rescResults; // buffer for results of dosexecpgm
599
600 strcpy(achProgram, "CMD.EXE /C ");
601 strcat(achProgram, """COPY ");
602 strcat(achProgram, filePath.get());
603 strcat(achProgram, " ");
604 strcat(achProgram, (PSZ)NS_CONST_CAST(char*, destPath.get()));
605 strcat(achProgram, """");
606 achProgram[strlen(achProgram) + 1] = '\0';
607 achProgram[7] = '\0';
608 DosExecPgm(NULL, 0,
609 EXEC_SYNC, achProgram, (PSZ)NULL,
610 &rescResults, achProgram);
611 rc = 0; // Assume it worked
612
613 } /* rc == 65 */
614 /* moving the file is supposed to act like a rename, so delete the
615 * original file if we got this far without error
616 */
617 if( move && (rc == NO_ERROR) )
618 {
619 DosDelete( filePath.get() );
620 }
621 } /* !move or ERROR */
622
623 if (rc)
624 rv = ConvertOS2Error(rc);
625
626 return rv;
627}
628
629
630nsresult
631nsLocalFile::CopyMove(nsIFile *aParentDir, const nsACString &newName, PRBool move)
632{
633 nsCOMPtr<nsIFile> newParentDir = aParentDir;
634
635 nsresult rv = Stat();
636 if (NS_FAILED(rv))
637 return rv;
638
639 if (!newParentDir)
640 {
641 // no parent was specified. We must rename.
642
643 if (newName.IsEmpty())
644 return NS_ERROR_INVALID_ARG;
645
646 rv = GetParent(getter_AddRefs(newParentDir));
647 if (NS_FAILED(rv))
648 return rv;
649 }
650
651 if (!newParentDir)
652 return NS_ERROR_FILE_DESTINATION_NOT_DIR;
653
654 // make sure it exists and is a directory. Create it if not there.
655 PRBool exists;
656 newParentDir->Exists(&exists);
657 if (exists == PR_FALSE)
658 {
659 rv = newParentDir->Create(DIRECTORY_TYPE, 0644); // TODO, what permissions should we use
660 if (NS_FAILED(rv))
661 return rv;
662 }
663 else
664 {
665 PRBool isDir;
666 newParentDir->IsDirectory(&isDir);
667 if (isDir == PR_FALSE)
668 {
669 return NS_ERROR_FILE_DESTINATION_NOT_DIR;
670 }
671 }
672
673 // check to see if we are a directory, if so enumerate it.
674
675 PRBool isDir;
676 IsDirectory(&isDir);
677
678 if (!isDir)
679 {
680 rv = CopySingleFile(this, newParentDir, newName, move);
681 if (NS_FAILED(rv))
682 return rv;
683 }
684 else
685 {
686 // create a new target destination in the new parentDir;
687 nsCOMPtr<nsIFile> target;
688 rv = newParentDir->Clone(getter_AddRefs(target));
689
690 if (NS_FAILED(rv))
691 return rv;
692
693 nsCAutoString allocatedNewName;
694 if (newName.IsEmpty())
695 {
696 GetNativeLeafName(allocatedNewName);// this should be the leaf name of the
697 }
698 else
699 {
700 allocatedNewName = newName;
701 }
702
703 rv = target->AppendNative(allocatedNewName);
704 if (NS_FAILED(rv))
705 return rv;
706
707 allocatedNewName.Truncate();
708
709 target->Create(DIRECTORY_TYPE, 0644); // TODO, what permissions should we use
710 if (NS_FAILED(rv))
711 return rv;
712
713 nsDirEnumerator* dirEnum = new nsDirEnumerator();
714 if (!dirEnum)
715 return NS_ERROR_OUT_OF_MEMORY;
716
717 rv = dirEnum->Init(this);
718
719 nsCOMPtr<nsISimpleEnumerator> iterator = do_QueryInterface(dirEnum);
720
721 PRBool more;
722 iterator->HasMoreElements(&more);
723 while (more)
724 {
725 nsCOMPtr<nsISupports> item;
726 nsCOMPtr<nsIFile> file;
727 iterator->GetNext(getter_AddRefs(item));
728 file = do_QueryInterface(item);
729 PRBool isDir, isLink;
730
731 file->IsDirectory(&isDir);
732
733 if (move)
734 {
735 rv = file->MoveToNative(target, nsCString());
736 }
737 else
738 {
739 rv = file->CopyToNative(target, nsCString());
740 }
741
742 iterator->HasMoreElements(&more);
743 }
744 // we've finished moving all the children of this directory
745 // in the new directory. so now delete the directory
746 // note, we don't need to do a recursive delete.
747 // MoveTo() is recursive. At this point,
748 // we've already moved the children of the current folder
749 // to the new location. nothing should be left in the folder.
750 if (move)
751 {
752 rv = Remove(PR_FALSE);
753 NS_ENSURE_SUCCESS(rv,rv);
754 }
755 }
756
757
758 // If we moved, we want to adjust this.
759 if (move)
760 {
761 MakeDirty();
762
763 nsCAutoString newParentPath;
764 newParentDir->GetNativePath(newParentPath);
765
766 if (newParentPath.IsEmpty())
767 return NS_ERROR_FAILURE;
768
769 if (newName.IsEmpty())
770 {
771 nsCAutoString aFileName;
772 GetNativeLeafName(aFileName);
773
774 InitWithNativePath(newParentPath);
775 AppendNative(aFileName);
776 }
777 else
778 {
779 InitWithNativePath(newParentPath);
780 AppendNative(newName);
781 }
782 }
783
784 return NS_OK;
785}
786
787NS_IMETHODIMP
788nsLocalFile::CopyToNative(nsIFile *newParentDir, const nsACString &newName)
789{
790 return CopyMove(newParentDir, newName, PR_FALSE);
791}
792
793NS_IMETHODIMP
794nsLocalFile::CopyToFollowingLinksNative(nsIFile *newParentDir, const nsACString &newName)
795{
796 return CopyMove(newParentDir, newName, PR_FALSE);
797}
798
799NS_IMETHODIMP
800nsLocalFile::MoveToNative(nsIFile *newParentDir, const nsACString &newName)
801{
802 return CopyMove(newParentDir, newName, PR_TRUE);
803}
804
805NS_IMETHODIMP
806nsLocalFile::Load(PRLibrary * *_retval)
807{
808 PRBool isFile;
809 nsresult rv = IsFile(&isFile);
810
811 if (NS_FAILED(rv))
812 return rv;
813
814 if (! isFile)
815 return NS_ERROR_FILE_IS_DIRECTORY;
816
817 *_retval = PR_LoadLibrary(mWorkingPath.get());
818
819 if (*_retval)
820 return NS_OK;
821
822 return NS_ERROR_NULL_POINTER;
823}
824
825NS_IMETHODIMP
826nsLocalFile::Remove(PRBool recursive)
827{
828 PRBool isDir;
829
830 nsresult rv = IsDirectory(&isDir);
831 if (NS_FAILED(rv))
832 return rv;
833
834 const char *filePath = mWorkingPath.get();
835
836 if (isDir)
837 {
838 if (recursive)
839 {
840 nsDirEnumerator* dirEnum = new nsDirEnumerator();
841 if (dirEnum == nsnull)
842 return NS_ERROR_OUT_OF_MEMORY;
843
844 rv = dirEnum->Init(this);
845
846 nsCOMPtr<nsISimpleEnumerator> iterator = do_QueryInterface(dirEnum);
847
848 PRBool more;
849 iterator->HasMoreElements(&more);
850 while (more)
851 {
852 nsCOMPtr<nsISupports> item;
853 nsCOMPtr<nsIFile> file;
854 iterator->GetNext(getter_AddRefs(item));
855 file = do_QueryInterface(item);
856
857 file->Remove(recursive);
858
859 iterator->HasMoreElements(&more);
860 }
861 }
862 rv = rmdir(filePath) == -1 ? NSRESULT_FOR_ERRNO() : NS_OK;
863 }
864 else
865 {
866 rv = remove(filePath) == -1 ? NSRESULT_FOR_ERRNO() : NS_OK;
867 }
868
869 MakeDirty();
870 return rv;
871}
872
873NS_IMETHODIMP
874nsLocalFile::GetLastModifiedTime(PRInt64 *aLastModifiedTime)
875{
876 NS_ENSURE_ARG(aLastModifiedTime);
877
878 *aLastModifiedTime = 0;
879
880 nsresult rv = Stat();
881
882 if (NS_FAILED(rv))
883 return rv;
884
885 // microseconds -> milliseconds
886 *aLastModifiedTime = mFileInfo64.modifyTime / PR_USEC_PER_MSEC;
887 return NS_OK;
888}
889
890
891NS_IMETHODIMP
892nsLocalFile::GetLastModifiedTimeOfLink(PRInt64 *aLastModifiedTime)
893{
894 return NS_ERROR_NOT_IMPLEMENTED;
895}
896
897
898NS_IMETHODIMP
899nsLocalFile::SetLastModifiedTime(PRInt64 aLastModifiedTime)
900{
901 return nsLocalFile::SetModDate(aLastModifiedTime);
902}
903
904
905NS_IMETHODIMP
906nsLocalFile::SetLastModifiedTimeOfLink(PRInt64 aLastModifiedTime)
907{
908 return NS_ERROR_NOT_IMPLEMENTED;
909}
910
911nsresult
912nsLocalFile::SetModDate(PRInt64 aLastModifiedTime)
913{
914 nsresult rv = Stat();
915
916 if (NS_FAILED(rv))
917 return rv;
918
919 const char *filePath = mWorkingPath.get();
920
921 PRExplodedTime pret;
922 FILESTATUS3 pathInfo;
923
924 rv = DosQueryPathInfo(filePath,
925 FIL_STANDARD, // Level 1 info
926 &pathInfo,
927 sizeof(pathInfo));
928
929 if (NS_FAILED(rv))
930 {
931 rv = ConvertOS2Error(rv);
932 return rv;
933 }
934
935 // PR_ExplodeTime expects usecs...
936 PR_ExplodeTime(aLastModifiedTime * PR_USEC_PER_MSEC, PR_LocalTimeParameters, &pret);
937 /* fdateLastWrite.year is based off of 1980 */
938 if (pret.tm_year >= 1980)
939 pathInfo.fdateLastWrite.year = pret.tm_year-1980;
940 else
941 pathInfo.fdateLastWrite.year = pret.tm_year;
942 pathInfo.fdateLastWrite.month = pret.tm_month + 1; // Convert start offset -- Win32: Jan=1; NSPR: Jan=0
943// ???? OS2TODO st.wDayOfWeek = pret.tm_wday;
944 pathInfo.fdateLastWrite.day = pret.tm_mday;
945 pathInfo.ftimeLastWrite.hours = pret.tm_hour;
946 pathInfo.ftimeLastWrite.minutes = pret.tm_min;
947 pathInfo.ftimeLastWrite.twosecs = pret.tm_sec / 2; // adjust for twosecs?
948// ??? OS2TODO st.wMilliseconds = pret.tm_usec/1000;
949
950 rv = DosSetPathInfo(filePath,
951 FIL_STANDARD, // Level 1 info
952 &pathInfo,
953 sizeof(pathInfo),
954 0UL);
955
956 if (NS_FAILED(rv))
957 return rv;
958
959 MakeDirty();
960 return rv;
961}
962
963NS_IMETHODIMP
964nsLocalFile::GetPermissions(PRUint32 *aPermissions)
965{
966 nsresult rv = Stat();
967
968 if (NS_FAILED(rv))
969 return rv;
970
971 const char *filePath = mWorkingPath.get();
972
973
974 return NS_OK;
975}
976
977NS_IMETHODIMP
978nsLocalFile::GetPermissionsOfLink(PRUint32 *aPermissionsOfLink)
979{
980 return NS_ERROR_NOT_IMPLEMENTED;
981}
982
983
984NS_IMETHODIMP
985nsLocalFile::SetPermissions(PRUint32 aPermissions)
986{
987 nsresult rv = Stat();
988
989 if (NS_FAILED(rv))
990 return rv;
991
992 const char *filePath = mWorkingPath.get();
993 if( chmod(filePath, aPermissions) == -1 )
994 return NS_ERROR_FAILURE;
995
996 return NS_OK;
997}
998
999NS_IMETHODIMP
1000nsLocalFile::SetPermissionsOfLink(PRUint32 aPermissions)
1001{
1002 return NS_ERROR_NOT_IMPLEMENTED;
1003}
1004
1005
1006NS_IMETHODIMP
1007nsLocalFile::GetFileSize(PRInt64 *aFileSize)
1008{
1009 NS_ENSURE_ARG(aFileSize);
1010
1011 *aFileSize = 0;
1012
1013 nsresult rv = Stat();
1014
1015 if (NS_FAILED(rv))
1016 return rv;
1017
1018
1019 *aFileSize = mFileInfo64.size;
1020 return NS_OK;
1021}
1022
1023
1024NS_IMETHODIMP
1025nsLocalFile::SetFileSize(PRInt64 aFileSize)
1026{
1027
1028 nsresult rv = Stat();
1029
1030 if (NS_FAILED(rv))
1031 return rv;
1032
1033 const char *filePath = mWorkingPath.get();
1034
1035
1036 APIRET rc;
1037 HFILE hFile;
1038 ULONG actionTaken;
1039
1040 rc = DosOpen(filePath,
1041 &hFile,
1042 &actionTaken,
1043 0,
1044 FILE_NORMAL,
1045 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
1046 OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE,
1047 NULL);
1048
1049 if (rc != NO_ERROR)
1050 {
1051 MakeDirty();
1052 return NS_ERROR_FAILURE;
1053 }
1054
1055 // Seek to new, desired end of file
1056 PRInt32 hi, lo;
1057 myLL_L2II(aFileSize, &hi, &lo );
1058
1059 rc = DosSetFileSize(hFile, lo);
1060 if (rc == NO_ERROR)
1061 DosClose(hFile);
1062 else
1063 goto error;
1064
1065 MakeDirty();
1066 return NS_OK;
1067
1068 error:
1069 MakeDirty();
1070 DosClose(hFile);
1071 return NS_ERROR_FAILURE;
1072}
1073
1074NS_IMETHODIMP
1075nsLocalFile::GetFileSizeOfLink(PRInt64 *aFileSize)
1076{
1077 return NS_ERROR_NOT_IMPLEMENTED;
1078}
1079
1080NS_IMETHODIMP
1081nsLocalFile::GetDiskSpaceAvailable(PRInt64 *aDiskSpaceAvailable)
1082{
1083 NS_ENSURE_ARG(aDiskSpaceAvailable);
1084
1085 ULONG ulDriveNo = toupper(mWorkingPath.CharAt(0)) + 1 - 'A';
1086 FSALLOCATE fsAllocate;
1087 APIRET rc = DosQueryFSInfo(ulDriveNo,
1088 FSIL_ALLOC,
1089 &fsAllocate,
1090 sizeof(fsAllocate));
1091
1092 if (rc != NO_ERROR)
1093 return NS_ERROR_FAILURE;
1094
1095 *aDiskSpaceAvailable = fsAllocate.cUnitAvail;
1096 *aDiskSpaceAvailable *= fsAllocate.cSectorUnit;
1097 *aDiskSpaceAvailable *= fsAllocate.cbSector;
1098
1099 return NS_OK;
1100}
1101
1102NS_IMETHODIMP
1103nsLocalFile::GetParent(nsIFile * *aParent)
1104{
1105 NS_ENSURE_ARG_POINTER(aParent);
1106
1107 nsCAutoString parentPath(mWorkingPath);
1108
1109 // cannot use nsCString::RFindChar() due to 0x5c problem
1110 PRInt32 offset = (PRInt32) (_mbsrchr((const unsigned char *) parentPath.get(), '\\')
1111 - (const unsigned char *) parentPath.get());
1112 if (offset < 0)
1113 return NS_ERROR_FILE_UNRECOGNIZED_PATH;
1114
1115 parentPath.Truncate(offset);
1116
1117 nsCOMPtr<nsILocalFile> localFile;
1118 nsresult rv = NS_NewNativeLocalFile(parentPath, PR_TRUE, getter_AddRefs(localFile));
1119
1120 if(NS_SUCCEEDED(rv) && localFile)
1121 {
1122 return CallQueryInterface(localFile, aParent);
1123 }
1124 return rv;
1125}
1126
1127NS_IMETHODIMP
1128nsLocalFile::Exists(PRBool *_retval)
1129{
1130 NS_ENSURE_ARG(_retval);
1131
1132 MakeDirty();
1133 *_retval = NS_SUCCEEDED(Stat());
1134
1135 return NS_OK;
1136}
1137
1138NS_IMETHODIMP
1139nsLocalFile::IsWritable(PRBool *_retval)
1140{
1141 NS_ENSURE_ARG(_retval);
1142 *_retval = PR_FALSE;
1143
1144 nsresult rv = Stat();
1145
1146 if (NS_FAILED(rv))
1147 return rv;
1148
1149 const char *workingFilePath = mWorkingPath.get();
1150
1151 APIRET rc;
1152 FILESTATUS3 pathInfo;
1153
1154 rc = DosQueryPathInfo(workingFilePath,
1155 FIL_STANDARD, // Level 1 info
1156 &pathInfo,
1157 sizeof(pathInfo));
1158
1159 if (rc != NO_ERROR)
1160 {
1161 rc = ConvertOS2Error(rc);
1162 return rc;
1163 }
1164
1165 *_retval = !((pathInfo.attrFile & FILE_READONLY) != 0);
1166
1167 return NS_OK;
1168}
1169
1170NS_IMETHODIMP
1171nsLocalFile::IsReadable(PRBool *_retval)
1172{
1173 NS_ENSURE_ARG(_retval);
1174 *_retval = PR_FALSE;
1175
1176 nsresult rv = Stat();
1177 if (NS_FAILED(rv))
1178 return rv;
1179
1180 *_retval = PR_TRUE;
1181 return NS_OK;
1182}
1183
1184
1185NS_IMETHODIMP
1186nsLocalFile::IsExecutable(PRBool *_retval)
1187{
1188 NS_ENSURE_ARG(_retval);
1189 *_retval = PR_FALSE;
1190
1191 nsresult rv = Stat();
1192 if (NS_FAILED(rv))
1193 return rv;
1194
1195 nsCAutoString path;
1196 GetNativeTarget(path);
1197
1198 const char* leaf = (const char*) _mbsrchr((const unsigned char*) path.get(), '\\');
1199
1200 if ( (strstr(leaf, ".bat") != nsnull) ||
1201 (strstr(leaf, ".exe") != nsnull) ||
1202 (strstr(leaf, ".cmd") != nsnull) ||
1203 (strstr(leaf, ".com") != nsnull) ) {
1204 *_retval = PR_TRUE;
1205 } else {
1206 *_retval = PR_FALSE;
1207 }
1208
1209 return NS_OK;
1210}
1211
1212
1213NS_IMETHODIMP
1214nsLocalFile::IsDirectory(PRBool *_retval)
1215{
1216 NS_ENSURE_ARG(_retval);
1217 *_retval = PR_FALSE;
1218
1219 nsresult rv = Stat();
1220
1221 if (NS_FAILED(rv))
1222 return rv;
1223
1224 *_retval = (mFileInfo64.type == PR_FILE_DIRECTORY);
1225
1226 return NS_OK;
1227}
1228
1229NS_IMETHODIMP
1230nsLocalFile::IsFile(PRBool *_retval)
1231{
1232 NS_ENSURE_ARG(_retval);
1233 *_retval = PR_FALSE;
1234
1235 nsresult rv = Stat();
1236
1237 if (NS_FAILED(rv))
1238 return rv;
1239
1240 *_retval = (mFileInfo64.type == PR_FILE_FILE);
1241 return rv;
1242}
1243
1244NS_IMETHODIMP
1245nsLocalFile::IsHidden(PRBool *_retval)
1246{
1247 NS_ENSURE_ARG(_retval);
1248 *_retval = PR_FALSE;
1249
1250 nsresult rv = Stat();
1251
1252 if (NS_FAILED(rv))
1253 return rv;
1254
1255 const char *workingFilePath = mWorkingPath.get();
1256
1257 APIRET rc;
1258 FILESTATUS3 pathInfo;
1259
1260 rc = DosQueryPathInfo(workingFilePath,
1261 FIL_STANDARD, // Level 1 info
1262 &pathInfo,
1263 sizeof(pathInfo));
1264
1265 if (rc != NO_ERROR)
1266 {
1267 rc = ConvertOS2Error(rc);
1268 return rc;
1269 }
1270
1271 *_retval = ((pathInfo.attrFile & FILE_HIDDEN) != 0);
1272
1273 return NS_OK;
1274}
1275
1276
1277NS_IMETHODIMP
1278nsLocalFile::IsSymlink(PRBool *_retval)
1279{
1280 NS_ENSURE_ARG_POINTER(_retval);
1281 // No Symlinks on OS/2
1282 *_retval = PR_FALSE;
1283
1284 return NS_OK;
1285}
1286
1287NS_IMETHODIMP
1288nsLocalFile::IsSpecial(PRBool *_retval)
1289{
1290 NS_ENSURE_ARG(_retval);
1291 *_retval = PR_FALSE;
1292
1293 nsresult rv = Stat();
1294
1295 if (NS_FAILED(rv))
1296 return rv;
1297
1298 const char *workingFilePath = mWorkingPath.get();
1299
1300 APIRET rc;
1301 FILESTATUS3 pathInfo;
1302
1303 rc = DosQueryPathInfo(workingFilePath,
1304 FIL_STANDARD, // Level 1 info
1305 &pathInfo,
1306 sizeof(pathInfo));
1307
1308 if (rc != NO_ERROR)
1309 {
1310 rc = ConvertOS2Error(rc);
1311 return rc;
1312 }
1313
1314 *_retval = ((pathInfo.attrFile & FILE_SYSTEM) != 0);
1315
1316 return NS_OK;
1317}
1318
1319NS_IMETHODIMP
1320nsLocalFile::Equals(nsIFile *inFile, PRBool *_retval)
1321{
1322 NS_ENSURE_ARG(inFile);
1323 NS_ENSURE_ARG(_retval);
1324 *_retval = PR_FALSE;
1325
1326 nsCAutoString inFilePath;
1327 inFile->GetNativePath(inFilePath);
1328
1329 *_retval = inFilePath.Equals(mWorkingPath);
1330 return NS_OK;
1331}
1332
1333NS_IMETHODIMP
1334nsLocalFile::Contains(nsIFile *inFile, PRBool recur, PRBool *_retval)
1335{
1336 *_retval = PR_FALSE;
1337
1338 nsCAutoString myFilePath;
1339 if ( NS_FAILED(GetNativeTarget(myFilePath)))
1340 GetNativePath(myFilePath);
1341
1342 PRInt32 myFilePathLen = myFilePath.Length();
1343
1344 nsCAutoString inFilePath;
1345 if ( NS_FAILED(inFile->GetNativeTarget(inFilePath)))
1346 inFile->GetNativePath(inFilePath);
1347
1348 if ( strnicmp( myFilePath.get(), inFilePath.get(), myFilePathLen) == 0)
1349 {
1350 // now make sure that the |inFile|'s path has a trailing
1351 // separator.
1352
1353 if (inFilePath[myFilePathLen] == '\\')
1354 {
1355 *_retval = PR_TRUE;
1356 }
1357
1358 }
1359
1360 return NS_OK;
1361}
1362
1363NS_IMETHODIMP
1364nsLocalFile::GetNativeTarget(nsACString &_retval)
1365{
1366 _retval = mWorkingPath;
1367 return NS_OK;
1368}
1369
1370/* attribute PRBool followLinks; */
1371NS_IMETHODIMP
1372nsLocalFile::GetFollowLinks(PRBool *aFollowLinks)
1373{
1374 *aFollowLinks = PR_TRUE;
1375 return NS_OK;
1376}
1377NS_IMETHODIMP
1378nsLocalFile::SetFollowLinks(PRBool aFollowLinks)
1379{
1380 return NS_OK;
1381}
1382
1383NS_IMETHODIMP
1384nsLocalFile::GetDirectoryEntries(nsISimpleEnumerator * *entries)
1385{
1386 nsresult rv;
1387
1388 *entries = nsnull;
1389
1390 PRBool isDir;
1391 rv = IsDirectory(&isDir);
1392 if (NS_FAILED(rv))
1393 return rv;
1394 if (!isDir)
1395 return NS_ERROR_FILE_NOT_DIRECTORY;
1396
1397 nsDirEnumerator* dirEnum = new nsDirEnumerator();
1398 if (dirEnum == nsnull)
1399 return NS_ERROR_OUT_OF_MEMORY;
1400 NS_ADDREF(dirEnum);
1401 rv = dirEnum->Init(this);
1402 if (NS_FAILED(rv))
1403 {
1404 NS_RELEASE(dirEnum);
1405 return rv;
1406 }
1407
1408 *entries = dirEnum;
1409 return NS_OK;
1410}
1411
1412NS_IMETHODIMP
1413nsLocalFile::GetPersistentDescriptor(nsACString &aPersistentDescriptor)
1414{
1415 return GetNativePath(aPersistentDescriptor);
1416}
1417
1418NS_IMETHODIMP
1419nsLocalFile::SetPersistentDescriptor(const nsACString &aPersistentDescriptor)
1420{
1421 return InitWithNativePath(aPersistentDescriptor);
1422}
1423
1424#ifndef OPEN_DEFAULT
1425#define OPEN_DEFAULT 0
1426#define OPEN_CONTENTS 1
1427#endif
1428
1429
1430NS_IMETHODIMP
1431nsLocalFile::Reveal()
1432{
1433 PRBool isDirectory = PR_FALSE;
1434 nsCAutoString path;
1435
1436 IsDirectory(&isDirectory);
1437 if (isDirectory)
1438 {
1439 GetNativePath(path);
1440 }
1441 else
1442 {
1443 nsCOMPtr<nsIFile> parent;
1444 GetParent(getter_AddRefs(parent));
1445 if (parent)
1446 parent->GetNativePath(path);
1447 }
1448
1449 HOBJECT hobject = WinQueryObject(path.get());
1450 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
1451 WinOpenObject( hobject, OPEN_CONTENTS, TRUE);
1452
1453 // we don't care if it succeeded or failed.
1454 return NS_OK;
1455}
1456
1457
1458NS_IMETHODIMP
1459nsLocalFile::Launch()
1460{
1461 HOBJECT hobject = WinQueryObject(mWorkingPath.get());
1462 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
1463 WinOpenObject( hobject, OPEN_DEFAULT, TRUE);
1464
1465 // we don't care if it succeeded or failed.
1466 return NS_OK;
1467}
1468
1469nsresult
1470NS_NewNativeLocalFile(const nsACString &path, PRBool followLinks, nsILocalFile* *result)
1471{
1472 nsLocalFile* file = new nsLocalFile();
1473 if (file == nsnull)
1474 return NS_ERROR_OUT_OF_MEMORY;
1475 NS_ADDREF(file);
1476
1477 if (!path.IsEmpty()) {
1478 nsresult rv = file->InitWithNativePath(path);
1479 if (NS_FAILED(rv)) {
1480 NS_RELEASE(file);
1481 return rv;
1482 }
1483 }
1484
1485 *result = file;
1486 return NS_OK;
1487}
1488
1489// Locates the first occurrence of charToSearchFor in the stringToSearch
1490static unsigned char* PR_CALLBACK
1491_mbschr( const unsigned char* stringToSearch, int charToSearchFor)
1492{
1493 const unsigned char* p = stringToSearch;
1494 do {
1495 if (*p == charToSearchFor)
1496 break;
1497 p = (const unsigned char*)WinNextChar(0,0,0,(char*)p);
1498 } while (*p); /* enddo */
1499 // Result is p or NULL
1500 return *p ? (unsigned char*)p : NULL;
1501}
1502
1503// Locates last occurence of charToSearchFor in the stringToSearch
1504extern unsigned char*
1505_mbsrchr( const unsigned char* stringToSearch, int charToSearchFor)
1506{
1507 int length = strlen((const char*)stringToSearch);
1508 const unsigned char* p = stringToSearch+length;
1509 do {
1510 if (*p == charToSearchFor)
1511 break;
1512 p = (const unsigned char*)WinPrevChar(0,0,0,(char*)stringToSearch,(char*)p);
1513 } while (p > stringToSearch); /* enddo */
1514 // Result is p or NULL
1515 return (*p == charToSearchFor) ? (unsigned char*)p : NULL;
1516}
1517
1518// Implement equivalent of Win32 CreateDirectoryA
1519static nsresult PR_CALLBACK
1520CreateDirectoryA( PSZ path, PEAOP2 ppEABuf)
1521{
1522 APIRET rc;
1523 nsresult rv;
1524 FILESTATUS3 pathInfo;
1525
1526 rc = DosCreateDir( path, ppEABuf );
1527 if (rc != NO_ERROR) {
1528 rv = ConvertOS2Error(rc);
1529
1530 // Check if directory already exists and if so, reflect that in the return value
1531 rc = DosQueryPathInfo(path,
1532 FIL_STANDARD, // Level 1 info
1533 &pathInfo,
1534 sizeof(pathInfo));
1535 if (rc == NO_ERROR)
1536 rv = ERROR_FILE_EXISTS;
1537 }
1538 else
1539 rv = rc;
1540
1541 return rv;
1542}
1543
1544static int isleadbyte(int c)
1545{
1546 static BOOL bDBCSFilled=FALSE;
1547 static BYTE DBCSInfo[12] = { 0 }; /* According to the Control Program Guide&Ref,
1548 12 bytes is sufficient */
1549 BYTE *curr;
1550 BOOL retval = FALSE;
1551
1552 if( !bDBCSFilled ) {
1553 COUNTRYCODE ctrycodeInfo = { 0 };
1554 APIRET rc = NO_ERROR;
1555 ctrycodeInfo.country = 0; /* Current Country */
1556 ctrycodeInfo.codepage = 0; /* Current Codepage */
1557
1558 rc = DosQueryDBCSEnv( sizeof( DBCSInfo ),
1559 &ctrycodeInfo,
1560 DBCSInfo );
1561 if( rc != NO_ERROR ) {
1562 /* we had an error, do something? */
1563 return FALSE;
1564 }
1565 bDBCSFilled=TRUE;
1566 }
1567
1568 curr = DBCSInfo;
1569 /* DBCSInfo returned by DosQueryDBCSEnv is terminated with two '0' bytes in a row */
1570 while(( *curr != 0 ) && ( *(curr+1) != 0)) {
1571 if(( c >= *curr ) && ( c <= *(curr+1) )) {
1572 retval=TRUE;
1573 break;
1574 }
1575 curr+=2;
1576 }
1577
1578 return retval;
1579}
1580
1581NS_IMETHODIMP
1582nsLocalFile::InitWithPath(const nsAString &filePath)
1583{
1584 if (filePath.IsEmpty())
1585 return InitWithNativePath(nsCString());
1586
1587 nsCAutoString tmp;
1588 nsresult rv = NS_CopyUnicodeToNative(filePath, tmp);
1589
1590 if (NS_SUCCEEDED(rv))
1591 return InitWithNativePath(tmp);
1592
1593 return rv;
1594}
1595
1596NS_IMETHODIMP
1597nsLocalFile::Append(const nsAString &node)
1598{
1599 if (node.IsEmpty())
1600 return NS_OK;
1601
1602 nsCAutoString tmp;
1603 nsresult rv = NS_CopyUnicodeToNative(node, tmp);
1604
1605 if (NS_SUCCEEDED(rv))
1606 return AppendNative(tmp);
1607
1608 return rv;
1609}
1610
1611NS_IMETHODIMP
1612nsLocalFile::AppendRelativePath(const nsAString &node)
1613{
1614 if (node.IsEmpty())
1615 return NS_OK;
1616
1617 nsCAutoString tmp;
1618 nsresult rv = NS_CopyUnicodeToNative(node, tmp);
1619
1620 if (NS_SUCCEEDED(rv))
1621 return AppendRelativeNativePath(tmp);
1622
1623 return rv;
1624}
1625
1626NS_IMETHODIMP
1627nsLocalFile::GetLeafName(nsAString &aLeafName)
1628{
1629 nsCAutoString tmp;
1630 nsresult rv = GetNativeLeafName(tmp);
1631
1632 if (NS_SUCCEEDED(rv))
1633 rv = NS_CopyNativeToUnicode(tmp, aLeafName);
1634
1635 return rv;
1636}
1637
1638NS_IMETHODIMP
1639nsLocalFile::SetLeafName(const nsAString &aLeafName)
1640{
1641 if (aLeafName.IsEmpty())
1642 return SetNativeLeafName(nsCString());
1643
1644 nsCAutoString tmp;
1645 nsresult rv = NS_CopyUnicodeToNative(aLeafName, tmp);
1646
1647 if (NS_SUCCEEDED(rv))
1648 return SetNativeLeafName(tmp);
1649
1650 return rv;
1651}
1652
1653NS_IMETHODIMP
1654nsLocalFile::GetPath(nsAString &_retval)
1655{
1656 return NS_CopyNativeToUnicode(mWorkingPath, _retval);
1657}
1658
1659NS_IMETHODIMP
1660nsLocalFile::CopyTo(nsIFile *newParentDir, const nsAString &newName)
1661{
1662 if (newName.IsEmpty())
1663 return CopyToNative(newParentDir, nsCString());
1664
1665 nsCAutoString tmp;
1666 nsresult rv = NS_CopyUnicodeToNative(newName, tmp);
1667
1668 if (NS_SUCCEEDED(rv))
1669 return CopyToNative(newParentDir, tmp);
1670
1671 return rv;
1672}
1673
1674NS_IMETHODIMP
1675nsLocalFile::CopyToFollowingLinks(nsIFile *newParentDir, const nsAString &newName)
1676{
1677 if (newName.IsEmpty())
1678 return CopyToFollowingLinksNative(newParentDir, nsCString());
1679
1680 nsCAutoString tmp;
1681 nsresult rv = NS_CopyUnicodeToNative(newName, tmp);
1682
1683 if (NS_SUCCEEDED(rv))
1684 return CopyToFollowingLinksNative(newParentDir, tmp);
1685
1686 return rv;
1687}
1688
1689NS_IMETHODIMP
1690nsLocalFile::MoveTo(nsIFile *newParentDir, const nsAString &newName)
1691{
1692 if (newName.IsEmpty())
1693 return MoveToNative(newParentDir, nsCString());
1694
1695 nsCAutoString tmp;
1696 nsresult rv = NS_CopyUnicodeToNative(newName, tmp);
1697
1698 if (NS_SUCCEEDED(rv))
1699 return MoveToNative(newParentDir, tmp);
1700
1701 return rv;
1702}
1703
1704NS_IMETHODIMP
1705nsLocalFile::GetTarget(nsAString &_retval)
1706{
1707 nsCAutoString tmp;
1708 nsresult rv = GetNativeTarget(tmp);
1709
1710 if (NS_SUCCEEDED(rv))
1711 rv = NS_CopyNativeToUnicode(tmp, _retval);
1712
1713 return rv;
1714}
1715
1716nsresult
1717NS_NewLocalFile(const nsAString &path, PRBool followLinks, nsILocalFile* *result)
1718{
1719 nsCAutoString buf;
1720 nsresult rv = NS_CopyUnicodeToNative(path, buf);
1721 if (NS_FAILED(rv)) {
1722 *result = nsnull;
1723 return rv;
1724 }
1725 return NS_NewNativeLocalFile(buf, followLinks, result);
1726}
1727
1728//----------------------------------------------------------------------------
1729// global init/shutdown
1730//----------------------------------------------------------------------------
1731
1732void
1733nsLocalFile::GlobalInit()
1734{
1735}
1736
1737void
1738nsLocalFile::GlobalShutdown()
1739{
1740}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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