VirtualBox

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

Last change on this file since 86423 was 62374, checked in by vboxsync, 8 years ago

xpcom: add missing breaks to ConvertWinError, ConvertOS2Error. This
code is not used, but keep static analyzers happy.

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