BRL-CAD
fchmod.c
Go to the documentation of this file.
1 /* F C H M O D . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2007-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #ifdef HAVE_SYS_TYPES_H
24 # include <sys/types.h>
25 #endif
26 #ifdef HAVE_SYS_STAT_H
27 # include <sys/stat.h>
28 #endif
29 #include "bio.h"
30 
31 #ifndef HAVE_FCHMOD
32 /* headers for the GetFileNameFromHandle() function below */
33 # include <tchar.h>
34 # include <string.h>
35 # include <psapi.h>
36 # include <strsafe.h>
37 #endif
38 
39 #include "bu/file.h"
40 #include "bu/str.h"
41 
42 #ifdef HAVE_FCHMOD
43 /* extern int fchmod(int, mode_t); */
44 /* use correct fchmod decl: */
45 # include <sys/stat.h>
46 #else
47 
48 /* Presumably Windows, pulled from MSDN sample code */
49 int
50 GetFileNameFromHandle(HANDLE hFile, char filepath[])
51 {
52  int bSuccess = 0;
53  TCHAR pszFilename[MAXPATHLEN+1];
54  char filename[MAXPATHLEN+1];
55  HANDLE hFileMap;
56 
57  /* Get the file size. */
58  DWORD dwFileSizeHi = 0;
59  DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);
60 
61  if (dwFileSizeLo == 0 && dwFileSizeHi == 0) {
62  _tprintf(TEXT("Cannot map a file with a length of zero.\n"));
63  return FALSE;
64  }
65 
66  /* Create a file mapping object. */
67  hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 1, NULL);
68 
69  if (hFileMap) {
70  /* Create a file mapping to get the file name. */
71  void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
72 
73  if (pMem) {
74  if (GetMappedFileName (GetCurrentProcess(), pMem, pszFilename, MAXPATHLEN)) {
75 
76  /* Translate path with device name to drive letters. */
77  TCHAR szTemp[MAXPATHLEN+1];
78  szTemp[0] = '\0';
79 
80  if (GetLogicalDriveStrings(MAXPATHLEN, szTemp)) {
81  TCHAR szName[MAXPATHLEN];
82  TCHAR szDrive[3] = TEXT(" :");
83  int bFound = 0;
84  TCHAR* p = szTemp;
85 
86  do {
87  /* Copy the drive letter to the template string */
88  *szDrive = *p;
89 
90  /* Look up each device name */
91  if (QueryDosDevice(szDrive, szName, MAXPATHLEN)) {
92  size_t uNameLen = _tcslen(szName);
93 
94  if (uNameLen < MAXPATHLEN) {
95  bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0;
96 
97  if (bFound && *(pszFilename + uNameLen) == _T('\\')) {
98  /* Reconstruct pszFilename using szTempFile */
99  /* Replace device path with DOS path */
100  TCHAR szTempFile[MAXPATHLEN];
101  StringCchPrintf(szTempFile, MAXPATHLEN, TEXT("%s%s"), szDrive, pszFilename+uNameLen);
102  StringCchCopyN(pszFilename, MAXPATHLEN+1, szTempFile, _tcslen(szTempFile));
103  }
104  }
105  }
106 
107  /* Go to the next NULL character. */
108  while (*p++);
109  } while (!bFound && *p)
110  ; /* end of string */
111  }
112  }
113  bSuccess = TRUE;
114  UnmapViewOfFile(pMem);
115  }
116 
117  CloseHandle(hFileMap);
118  }
119  if (sizeof(TCHAR) == sizeof(wchar_t)) {
120  wcstombs(filename, (const wchar_t *)pszFilename, MAXPATHLEN);
121  bu_strlcpy(filepath, filename, MAXPATHLEN);
122  } else {
123  bu_strlcpy(filepath, pszFilename, MAXPATHLEN);
124  }
125  return (bSuccess);
126 }
127 #endif
128 
129 
130 int
131 bu_fchmod(int fd,
132  unsigned long pmode)
133 {
134 #ifdef HAVE_FCHMOD
135  return fchmod(fd, (mode_t)pmode);
136 #else
137  /* Presumably Windows, so get dirty. We can call chmod() instead
138  * of fchmod(), but that means we need to know the file name.
139  * This isn't portably knowable, but Windows provides a roundabout
140  * way to figure it out.
141  *
142  * If we were willing to limit ourselves to Windows 2000 or 7+, we
143  * could call GetModuleFileNameEx() but there are reports that
144  * it's rather unreliable.
145  */
146  {
147  char filepath[MAXPATHLEN+1];
148  HANDLE h = (HANDLE)_get_osfhandle(fd);
149  GetFileNameFromHandle(h, filepath);
150  return chmod(filepath, pmode);
151  }
152 #endif
153 }
154 
155 
156 /*
157  * Local Variables:
158  * mode: C
159  * tab-width: 8
160  * indent-tabs-mode: t
161  * c-file-style: "stroustrup"
162  * End:
163  * ex: shiftwidth=4 tabstop=8
164  */
char filename[MAXLENGTH]
Definition: human.c:105
#define FALSE
int bu_fchmod(int fd, unsigned long pmode)
Definition: fchmod.c:131
Header file for the BRL-CAD common definitions.
#define TCHAR
Definition: vlist.c:486
#define bu_strlcpy(dst, src, size)
Definition: str.h:60
#define TRUE
int GetFileNameFromHandle(HANDLE hFile, char filepath[])
Definition: fchmod.c:50
#define MAXPATHLEN
Definition: defines.h:113