コード例 #1
0
ファイル: wcrtomb.c プロジェクト: mirror/mingw-org-wsl
size_t
wcrtomb (char *dst, wchar_t wc, mbstate_t * __UNUSED_PARAM (ps))
{
  char byte_bucket [MB_LEN_MAX];
  char* tmp_dst = dst ? dst : byte_bucket;      
  return (size_t)__wcrtomb_cp (tmp_dst, wc, get_codepage (),
			       MB_CUR_MAX);
}
コード例 #2
0
ファイル: wctob.c プロジェクト: mmcx/cegcc
/* Return just the first byte after translating to multibyte.  */
int wctob (wint_t wc )
{
    wchar_t w = wc;
    char c;
    int invalid_char = 0;
    if (!WideCharToMultiByte (get_codepage(), 
			      0 /* Is this correct flag? */,
			      &w, 1, &c, 1, NULL, &invalid_char)
         || invalid_char)
      return EOF;
    return (int) c;
}
コード例 #3
0
ファイル: btowc.c プロジェクト: mirror/mingw-org-wsl
wint_t btowc (int c)
{
  if (c == EOF)
    return (WEOF);
  else
    {
      unsigned char ch = c;
      wchar_t wc = WEOF;
      MultiByteToWideChar (get_codepage(), MB_ERR_INVALID_CHARS,
			   (char*)&ch, 1, &wc, 1);
      return wc;
    }
}
コード例 #4
0
ファイル: wcrtomb.c プロジェクト: mirror/mingw-org-wsl
size_t wcsrtombs (char *dst, const wchar_t **src, size_t len,
		  mbstate_t * __UNUSED_PARAM (ps))
{
  int ret = 0;
  size_t n = 0;
  const unsigned int cp = get_codepage();
  const unsigned int mb_max = MB_CUR_MAX;
  const wchar_t *pwc = *src;
  
  if (src == NULL || *src == NULL) /* undefined behavior */
     return 0;

  if (dst != NULL)
    {
       while (n < len)
        {
          if ((ret = __wcrtomb_cp (dst, *pwc, cp, mb_max)) <= 0)
	     return (size_t) -1;
  	  n += ret;
   	  dst += ret;
          if (*(dst - 1) == '\0')
	    {
	      *src = (wchar_t*) NULL;;
	      return (n  - 1);
	    }
	  pwc++;
        }
      *src = pwc;
    }
  else
    {
      char byte_bucket [MB_LEN_MAX];
      while (n < len)
        {
	  if ((ret = __wcrtomb_cp (byte_bucket, *pwc, cp, mb_max))
		 <= 0)
 	    return (size_t) -1;    
	  n += ret;
	  if (byte_bucket [ret - 1] == '\0')
	    return (n - 1);
          pwc++;
        }
    }
 
  return n;
}
コード例 #5
0
ファイル: Registry.cpp プロジェクト: somian/fileutil-ls
BOOL
print_registry_value(struct cache_entry *ce)
{
	struct find_reg *fr;
	struct _finddatai64_t fd;
	wchar_t wszName[FILENAME_MAX];
	DWORD dwSize=0;
	DWORD dwType;
	DWORD dwGotType=0;
	LONG lErrCode;

	typedef LONG (WINAPI *PFNREGQUERYREFLECTIONKEY)(
		HKEY hBase,
		BOOL *pbIsReflectionDisabled  // BUG in MSDN doc: BOOL
	);
	static PFNREGQUERYREFLECTIONKEY pfnRegQueryReflectionKey;

	fr = (struct find_reg*)xmalloc(sizeof(*fr));
	memset(fr, 0, sizeof(*fr));
	fr->fr_magic = FR_MAGIC;

	if (ce->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
		dwType = DT_DIR;
	} else {
		dwType = DT_REG;
	}

	if (!_PrepReg(ce->ce_abspath, fr, dwType)) {
		_RegFindClose((long)fr);
		return FALSE;
	}

	if (!_LookupReg(fr, &fd)) {
		_RegFindClose((long)fr);
		return FALSE;
	}

	if (dwType == DT_DIR) {
		//
		// Reg key: show the class name if any.
		//
		if (fr->fr_szClass != NULL) {
			more_printf("            Class Name: \"%s\"\n", fr->fr_szClass);
		}
		//
		// Reg key: report if 64-bit <-> 32-bit reflection is enabled.
		//
		// The reflection is between HKLM\Software and
		// HKLM\Software\Wow6432Node.
		//
		if (gbIsWindowsWOW64) {
		  if (DynaLoad("ADVAPI32.DLL", "RegQueryReflectionKey", 
				(PPFN)&pfnRegQueryReflectionKey)) {
			//
			// BUG: Documented as bReflectionEnabled but really
			// is bReflectionDisabled!
			//
			// Note: Always FALSE if !gbIsWindowsWOW64
			//
			// See http://www.codeproject.com/system/Reflection.asp
			//
			BOOL bReflectionDisabled = FALSE; // BUG: Reversed
			if ((*pfnRegQueryReflectionKey)(fr->fr_hKey, &bReflectionDisabled) == ERROR_SUCCESS) {
				if (!IsWindows7) { // Windows 7 disables all reflection always
					if (bReflectionDisabled) { // BUG: Reversed
						more_printf("            Reflection is disabled.\n");
					}
				}
			}
		  }
		}
		_RegFindClose((long)fr);
		return TRUE;
	}

	//
	// Show the reg value
	//

	if (fr->fr_szValue == NULL) {
		_RegFindClose((long)fr);
		return FALSE;
	}

	//
	// Query a single value - just check existance and get size
	//
	// BUG: Must use Unicode as the RegA functions wrongly
	// use the Ansi code page.
	if (::MultiByteToWideChar(get_codepage(), 0, fr->fr_szValue, -1,
			wszName, FILENAME_MAX) == 0) {
		_RegFindClose((long)fr);
		return FALSE;
	}

	if (wcscmp(wszName, L"[default]") == 0) {
		wszName[0] = L'\0';
	}

	dwSize = (DWORD)(fd.size);

	dwSize = (dwSize + 10) * sizeof(WCHAR);

	BOOL bUnicode = TRUE;
	PBYTE pbData = (PBYTE) alloca(dwSize);
	memset(pbData, 0, dwSize);

	//
	// Note: RegQueryValueExW will fail on Win9x
	//
	if ((lErrCode = ::RegQueryValueExW(fr->fr_hKey, wszName, 0,
			&dwGotType, pbData, &dwSize)) != ERROR_SUCCESS) {
		if (lErrCode != ERROR_NOT_SUPPORTED && lErrCode != ERROR_CALL_NOT_IMPLEMENTED) {
			::SetLastError((DWORD)lErrCode);
			_RegFindClose((long)fr);
			return FALSE;
		}
		//
		// Win9x: Try again using the ANSI version.
		// Note that this will wrongly convert OEM chars.
		//
		if ((lErrCode = ::RegQueryValueExA(fr->fr_hKey, fr->fr_szValue, 0,
				&dwGotType, pbData, &dwSize)) != ERROR_SUCCESS) {
			::SetLastError((DWORD)lErrCode);
			_RegFindClose((long)fr);
			return FALSE;
		}
		bUnicode = FALSE;
	}

	BOOL bExpandedMui = FALSE;

	if (IsVista && gbExpandMui) {
		if ((dwGotType == REG_SZ || dwGotType == REG_EXPAND_SZ || dwGotType == REG_MULTI_SZ)
			&& dwSize >= sizeof(WCHAR) && ((LPCWSTR)pbData)[0] == L'@'
			&& DynaLoad("ADVAPI32.DLL", "RegLoadMUIStringW", (PPFN)&pfnRegLoadMUIStringW)) {
			PBYTE pbMuiData = NULL;
			//
			// Get the required buffer size for the expanded MUI string
			//
			DWORD dwMuiLen = 0; // byte len
			WCHAR wszDummy[4]; // dummy buffer
			wszDummy[0] = L'\0';
			if ((lErrCode = (*pfnRegLoadMUIStringW)(fr->fr_hKey, wszName,
					wszDummy, 0, &dwMuiLen, 0, NULL)) != ERROR_MORE_DATA) {
				goto NoMui; // Use the @-string as-is
			}

			pbMuiData = (PBYTE) alloca(dwMuiLen+8);

			//
			// Now read the data for real
			//
			// dwMuiLen will be overwritten with the actual length
			//
			if ((lErrCode = (*pfnRegLoadMUIStringW)(fr->fr_hKey, wszName,
					(LPWSTR)pbMuiData, dwMuiLen, &dwMuiLen, 0, NULL)) != ERROR_SUCCESS) {
				goto NoMui; // Use the @-string as-is
			}
			//
			// Replace pbData with the expanded MUI data
			//
			pbData = pbMuiData;
			dwSize = dwMuiLen;

			bExpandedMui = TRUE;
		}
	}

NoMui:

	fd.size = dwSize;
	_RegFindClose((long)fr);

	switch (dwGotType) {

		case REG_SZ:
		case REG_EXPAND_SZ:
		{
			DWORD dwLen, dwStrLen=0;
			LPSTR szBuf;

			more_fputs((dwGotType == REG_SZ ?
				"            REG_SZ=\"" : "            REG_EXPAND_SZ=\""), stdmore);
			if (!bUnicode) {
				more_fputs((LPCSTR)pbData, stdmore);
				dwLen = dwSize;
				dwStrLen = strlen((LPCSTR)pbData) + 1;
			} else {
				dwLen = dwSize+10;
				szBuf = (LPSTR)alloca(dwLen);
				if ((dwLen = ::WideCharToMultiByte(get_codepage(), 0,
						(LPCWSTR)pbData, dwSize/2, szBuf, dwLen, NULL, NULL)) == 0) {
					more_fputs("???", stdmore);
				} else {
					more_fputs(szBuf, stdmore);
					dwStrLen = strlen(szBuf) + 1;
				}
			}
			more_fputs("\"\n", stdmore);
			if (dwLen != dwStrLen) {
				//
				// Warn if the string length does not match the registry
				// buffer size.  Could indicate hidden data after \0
				//
				more_printf("            *** String length with \\0 (%u) <> registry length (%u) ***\n",
					dwStrLen, dwLen);
			}
			break;
		}

		case REG_NONE:
		case REG_BINARY:
		case REG_LINK:
		case REG_MULTI_SZ:
		case REG_RESOURCE_LIST:
		case REG_FULL_RESOURCE_DESCRIPTOR:
		case REG_RESOURCE_REQUIREMENTS_LIST:
		default:
		{
			DWORD dwBytes, i;
			char ch;

			switch (dwGotType) {
				case REG_NONE:
					more_printf("            REG_NONE  (%u bytes)\n", dwSize);
					break;
				case REG_BINARY:
					more_printf("            REG_BINARY  (%u bytes)\n", dwSize);
					break;
				case REG_LINK:
					more_printf("            REG_LINK  (%u bytes)\n", dwSize);
					break;
				case REG_MULTI_SZ:
					more_printf("            REG_MULTI_SZ  (%u bytes)\n", dwSize);
					break;
				case REG_RESOURCE_LIST:
					more_printf("            REG_RESOURCE_LIST  (%u bytes)\n", dwSize);
					break;
				case REG_FULL_RESOURCE_DESCRIPTOR:
					more_printf("            REG_FULL_RESOURCE_DESCRIPTOR  (%u bytes)\n", dwSize);
					break;
				case REG_RESOURCE_REQUIREMENTS_LIST:
					more_printf("            REG_RESOURCE_REQUIREMENTS_LIST  (%u bytes)\n", dwSize);
					break;
				default:
					more_printf("            Unknown type (%u), size %u bytes.\n",
						dwGotType, dwSize);
					break;
			}

			for (unsigned long l=0; l < dwSize; l += 16) {
				more_printf("%8x: ", l);
				dwBytes = ((dwSize - l < 16) ? (dwSize - l) : 16);
				for (i=0; i < dwBytes; ++i) {
					more_printf("%02.2x ", pbData[l+i]);
				}
				for (; i < 16; ++i) {
					more_fputs("   ", stdmore);
				}
				more_fputs("  ", stdmore);

				for (i=0; i < dwBytes; ++i) {
					if ((ch = pbData[l+i]) < 040 || ch > 0176) {
						ch = '.';
					}
					more_putc(ch, stdmore);
				}

				for (; i < 16; ++i) {
					more_putc(' ', stdmore);
				}
				more_putc('\n', stdmore);
			}
			break;
		}

		case REG_DWORD:
			more_printf("            REG_DWORD=%u (0x%08X)\n", 
				*(PDWORD)pbData, *(PDWORD)pbData);
			if (dwSize != sizeof(DWORD)) {
				more_printf("            *** DWORD length (%u) is not standard. ***\n",
					dwSize);
			}
			break;

		case REG_QWORD:
			more_printf("            REG_QWORD=%I64u (0x%I64X)\n", 
				*(unsigned __int64 *)pbData, *(unsigned __int64 *)pbData);
			if (dwSize != sizeof(unsigned __int64)) {
				more_printf("            *** QWORD length (%u) is not standard. ***\n",
					dwSize);
			}
			break;
	}

	if (bExpandedMui) {
			more_printf("                Expanded MUI string.\n");
	}

	return TRUE;
}
コード例 #6
0
ファイル: Registry.cpp プロジェクト: somian/fileutil-ls
//
// Query a symbolic registry link
//
// Also do --regsetval and --regdelval
//
char *
_GetRegistryLink(struct cache_entry *ce, char *szPath)
{
	struct find_reg *fr;

	if ((ce->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
		return NULL; // regval
	}

	fr = (struct find_reg*)xmalloc(sizeof(*fr));
	memset(fr, 0, sizeof(*fr));
	fr->fr_magic = FR_MAGIC;

	DWORD dwType = DT_DIR;

	if (!_PrepReg(ce->ce_abspath, fr, dwType) || fr->fr_szKey == NULL) {
		_RegFindClose((long)fr);
		return NULL;
	}

	wchar_t wszPath[FILENAME_MAX+1];

	//
	// Convert the registry path to Unicode
	//
	if (MultiByteToWideChar(get_codepage(), 0, fr->fr_szKey, -1, 
			wszPath, FILENAME_MAX) == 0) {
		_RegFindClose((long)fr);
		return NULL;
	}

	LONG lErrCode;
	DWORD dwDisposition = 0;
	HKEY hkLink = NULL;

	DWORD dwAccess = KEY_READ;
	if (gbRegDelVal || gbRegSetVal) {
		dwAccess |= KEY_WRITE;
	}

	if (gbIsWindowsWOW64 && !gb32bit) {
		// Allow access to 64 bit keys
		dwAccess |= 0x0100; // KEY_WOW64_64KEY
	}

	//
	// Must use RegCreateKeyExW to pass REG_OPTION_OPEN_LINK
	//
	lErrCode = RegCreateKeyExW(fr->fr_hRoot,
		wszPath,
		0, NULL/*wszClass*/,
		REG_OPTION_OPEN_LINK,
		dwAccess, NULL, &hkLink, &dwDisposition);

	if (lErrCode != 0) {
		_RegFindClose((long)fr);
		return NULL;
	}

	dwType = 0;
	WCHAR wszData[FILENAME_MAX+1];
	DWORD dwLen = FILENAME_MAX*sizeof(WCHAR);

	wszData[0] = L'\0';

	lErrCode = RegQueryValueExW(hkLink, L"SymbolicLinkValue", NULL, &dwType,
		(PBYTE)wszData, &dwLen);

	if (gbRegDelVal) {
		//
		// --regdelval   Delete a test value for exploring registry reflection
		// and registry redirection.
		//
		::RegDeleteValueW(hkLink, L"TestValue");
	}

	if (gbRegSetVal) {
		//
		// --regsetval   Set a test value for exploring registry reflection
		// and registry redirection.
		//
		DWORD dwVal = 1;
		::RegSetValueExW(hkLink, L"TestValue", 0, REG_DWORD,
			(PBYTE)&dwVal, sizeof(dwVal));
	}

	RegCloseKey(hkLink); hkLink = NULL;

	//
	// Sanity check: If we somehow created a new key accidentally
	// via RegCreateKeyEx, bail immediately!
	//
	if (dwDisposition == REG_CREATED_NEW_KEY) {
		more_printf("Error: Created new key by mistake: %s\n",
			fr->fr_szKey);
		_RegFindClose((long)fr);
		exit(1);
	}

	_RegFindClose((long)fr);

	if (lErrCode != 0) {
		return NULL;
	}

	wszData[dwLen/2] = L'\0'; // BUG: Not NULL terminated

	//
	// Convert from wchar_t to multibyte string
	//
	if (!WideCharToMultiByte(get_codepage(), 0,
			wszData, -1,
			szPath, FILENAME_MAX-1, NULL, NULL)) {
		return NULL;
	}

	return szPath; 
}
コード例 #7
0
bool IE_Imp_MSWrite::read_ffntb ()
{
	int pnFfntb, pnMac, fonts_count = 0, cbFfn, fflen;
	unsigned char buf[2], ffid;
	wri_font *fonts;
	char *ffn;

	UT_DEBUGMSG(("Fonts:\n"));

	pnFfntb = wri_struct_value(wri_file_header, "pnFfntb");
	pnMac = wri_struct_value(wri_file_header, "pnMac");

	// if pnFfntb is the same as pnMac, there are no fonts
	if (pnFfntb == pnMac)
	{
		UT_DEBUGMSG((" (none)\n"));
		return true;
	}

	if (gsf_input_seek(mFile, pnFfntb++ * 0x80, G_SEEK_SET))
	{
		UT_WARNINGMSG(("read_ffntb: Can't seek FFNTB!\n"));
		return false;
	}

	// the first two bytes are the number of fonts
	if (!gsf_input_read(mFile, 2, buf))
	{
		UT_WARNINGMSG(("read_ffntb: Can't read FFNTB!\n"));
		return false;
	}

	wri_fonts_count = READ_WORD(buf);
	UT_DEBUGMSG((" reported: %d\n", wri_fonts_count));

	while (true)
	{
		if (!gsf_input_read(mFile, 2, buf))
		{
			UT_WARNINGMSG(("read_ffntb: Can't read cbFfn!\n"));
			wri_fonts_count = fonts_count;
			free_ffntb();
			return false;
		}

		cbFfn = READ_WORD(buf);

		if (cbFfn == 0) break;

		if (cbFfn == 0xffff)
		{
			if (gsf_input_seek(mFile, pnFfntb++ * 0x80, G_SEEK_SET))
			{
				UT_WARNINGMSG(("read_ffntb: Can't seek next FFNTB!\n"));
				wri_fonts_count = fonts_count;
				free_ffntb();
				return false;
			}

			continue;
		}

		// add one more font
		fonts = (wri_font *) realloc(wri_fonts, (fonts_count + 1) * sizeof(wri_font));

		if (!fonts)
		{
			UT_WARNINGMSG(("read_ffntb: Out of memory!\n"));
			wri_fonts_count = fonts_count;
			free_ffntb();
			return false;
		}

		wri_fonts = fonts;

		// This is the font family identifier. It can either be FF_DONTCARE,
		// FF_ROMAN, FF_SWISS, FF_MODERN, FF_SCRIPT or FF_DECORATIVE. These
		// are defined in <windows.h>, but I don't know what to do with them.
		if (!gsf_input_read(mFile, 1, &ffid))
		{
			UT_WARNINGMSG(("read_ffntb: Can't read ffid!\n"));
			wri_fonts_count = fonts_count;
			free_ffntb();
			return false;
		}

		wri_fonts[fonts_count].ffid = ffid;

		cbFfn--;   // we've already read ffid

		ffn = static_cast<char *>(malloc(cbFfn));

		if (!ffn)
		{
			UT_WARNINGMSG(("read_ffntb: Out of memory!\n"));
			wri_fonts_count = fonts_count;
			free_ffntb();
			return false;
		}

		if (!gsf_input_read(mFile, cbFfn, (guint8 *) ffn))
		{
			UT_WARNINGMSG(("read_ffntb: Can't read szFfn!\n"));
			wri_fonts_count = fonts_count + 1;
			free_ffntb();
			return false;
		}

		wri_fonts[fonts_count].codepage = get_codepage(ffn, &fflen);

		ffn[fflen] = 0;
		wri_fonts[fonts_count].name = ffn;

		UT_DEBUGMSG(("  %2d: %s (%s)\n", fonts_count, wri_fonts[fonts_count].name, wri_fonts[fonts_count].codepage));
		fonts_count++;
	}

	if (fonts_count != wri_fonts_count)
	{
		wri_fonts_count = fonts_count;
		UT_WARNINGMSG(("read_ffntb: Wrong number of fonts.\n"));
	}

	return true;
}
コード例 #8
0
ファイル: Streams.c プロジェクト: somian/fileutil-ls
//
// We do the actual digging into NTFS here
//
static BOOL
_LookupStream(BOOL bFirst,
	struct find_stream *fs, 
	char *szStreamMatch,
	struct _finddatai64_t *pfd)
{
	char szBuf[FILENAME_MAX*2];
	char *sz;
	HANDLE hFile;
#ifdef QUERY_EXTENDED_ATTRIBUTES
	PFILE_EA_INFORMATION pEaInfo = (PFILE_EA_INFORMATION) abEaInfo;
	//PFILE_FULL_EA_INFORMATION pFullEaInfo = (PFILE_FULL_EA_INFORMATION) abEaInfo;
#endif
	PFILE_STREAM_INFORMATION pStreamInfo = (PFILE_STREAM_INFORMATION) abStreamInfo;
	NTSTATUS Status;
	IO_STATUS_BLOCK IoStatus;
	struct stream_info *si, **psiPrev;

	if (fs->fs_next_stream_info != NULL) {
		goto next_si_entry;
	}

next_fs_entry:

	if (!bFirst) { // if _xfindnexti64()
		//
		// Get next file in list
		//
		if (_aefindnexti64(fs->fs_handle, pfd) < 0) {
			if (GetLastError() == ERROR_NO_MORE_FILES) {
				fs->fs_bEof = TRUE;
			}
			return FALSE; // splat
		}
	}

	//
	// pfd is loaded with real file data at this point
	//

	fs->fs_fd = *pfd; // get main file info - struct copy

	if ((pfd->attrib & (FILE_ATTRIBUTE_DEVICE|FILE_ATTRIBUTE_REPARSE_POINT)) != 0) {
		return TRUE; // no streams for devices or reparse-points
	}

	if (!DynaLoad("NTDLL.DLL", "NtQueryInformationFile", &pfnNtQueryInformationFile)) {
		goto done;
	}
	
#ifdef UNDEFINED
	if (!DynaLoad("NTDLL.DLL", "NtSetInformationFile", &pfnNtSetInformationFile)) {
		goto done;
	}
#endif

	//
	// Build path from fs->fs_szStrippedPath minus rightmost chunk
	// + '\\' + pfd->name
	//
	lstrcpyn(szBuf, fs->fs_szStrippedPath, FILENAME_MAX);
	if ((sz = strrchr(szBuf, '\\')) == NULL) {
		lstrcpyn(szBuf, pfd->name, FILENAME_MAX); // should never happen
	} else {
		lstrcpyn(sz+1, pfd->name, FILENAME_MAX);
	}

	//
	// Open the file with Backup semantics.
	//
	// UNDOCUMENTED: CreateFile does *not* require the
	// SeBackupPrivilege if the mode flags are 0!
	//
	// In all other cases FILE_FLAG_BACKUP_SEMANTICS requires
	// the SeBackupPrivilege.
	//
	if ((hFile = CreateFile(szBuf,
				0, // required - undocumented
				FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
				OPEN_EXISTING,
				FILE_FLAG_BACKUP_SEMANTICS, 0)) == INVALID_HANDLE_VALUE) {
		goto done;
	}

#ifdef QUERY_EXTENDED_ATTRIBUTES
	//
	// First query for Extended Attributes
	//
	Status = (*pfnNtQueryInformationFile)(hFile, &IoStatus, pEaInfo,
		EA_BUFSIZE, FileEaInformation/*7*/);

	if (NT_SUCCESS(Status) && pEaInfo->EaInformationLength != 0) {
		//
		// File has Extended Attributes
		//
		fd.Attribs |= FILE_ATTRIBUTE_EA;
	}
#endif

	//
	// Now query for streams
	//
	Status = (*pfnNtQueryInformationFile)(hFile, &IoStatus, pStreamInfo,
		STREAM_BUFSIZE, FileStreamInformation/*22*/);

	if (!NT_SUCCESS(Status)) {
		CloseHandle(hFile);
		MapNtStatusToWin32Error(Status);
		goto done;
	}

	if (IoStatus.Information == 0) { // pending??
		CloseHandle(hFile);
		SetLastError(ERROR_IO_PENDING); // should never happen
		goto done;
	}

	CloseHandle(hFile);

	//
	// BUG: We cannot enumerate streams for "." because it looks too
	// much like a drive letter (".:foo").  
	//
	// It triggers bugs in FILESYSTEM_PREFIX_LEN, glob.c, basename.c,
	// and many other places that check for szPath[1] == ':'.
	//
	if (strcmp(pfd->name, ".") == 0) {
		//
		// Indicate that dot has streams
		//
		pfd->attrib |= FILE_ATTRIBUTE_STREAMS;
		//
		// But do not enumerate them
		//
		goto done;
	}

	psiPrev = &fs->fs_list_stream_info;
	*psiPrev = NULL;

	for (;;) {
		char szPath[FILENAME_MAX];

		memset(szPath, 0, FILENAME_MAX); // required!

		//
		// Convert from wchar_t to multibyte string
		//
		if (!WideCharToMultiByte(get_codepage(), 0,
				pStreamInfo->StreamName,
				pStreamInfo->StreamNameLength / sizeof(WCHAR),
				szPath, FILENAME_MAX, NULL, NULL)) {
			break; // rare, ignore
		}

		if (stricmp(szPath, "::$DATA") != 0) { // skip default data stream
			//
			// Create a new stream_info obj
			//
			si = (struct stream_info *)xmalloc(sizeof(*si));
			memset(si, 0, sizeof(*si));
			si->si_szName = xstrdup(szPath);
			si->si_size = pStreamInfo->EndOfStream.QuadPart;
			si->si_phys_size = pStreamInfo->AllocationSize.QuadPart;

			// append to list
			*psiPrev = si; psiPrev = &si->si_next;
		}

		//
		// Bump to next FILE_STREAM_INFORMATION struct
		//
		if (pStreamInfo->NextEntryOffset == 0) { // end of chain
			*psiPrev = NULL;
			break;
		}
		pStreamInfo = (PFILE_STREAM_INFORMATION)
			(((char *)pStreamInfo) + pStreamInfo->NextEntryOffset);
	}

	// rewind to start
	fs->fs_next_stream_info = fs->fs_list_stream_info;

	if (fs->fs_list_stream_info != NULL) {
		//
		// Mark the file as having streams
		//
		pfd->attrib |= FILE_ATTRIBUTE_STREAMS;
		fs->fs_fd.attrib |= FILE_ATTRIBUTE_STREAMS; // mark children too
	}

	if (szStreamMatch == NULL) { // if want main file info
		return TRUE; // return of main file info
	}

	// fall through and return a matching stream

next_si_entry:
	
	if (fs->fs_next_stream_info == NULL) {
		goto next_fs_entry;
	}

	// pop next si entry
	si = fs->fs_next_stream_info;
	fs->fs_next_stream_info = si->si_next;

	*pfd = fs->fs_fd; // get main file info - struct copy

	//
	// Turn off the directory attribute - a stream is not a directory
	// (although a directory can have streams)
	//
	pfd->attrib &= ~FILE_ATTRIBUTE_DIRECTORY;

	//
	// See if stream does not match pattern
	//
	// Only match on direct match or '*'
	//
	if (szStreamMatch != NULL && 
		((szStreamMatch[0] != ':' || szStreamMatch[1] != '*' || szStreamMatch[2] != '\0') &&
			_mbsicmp(szStreamMatch, si->si_szName) != 0)) {
		// stream does not match pattern
		goto next_si_entry;
	}

	if (strlen(pfd->name) + strlen(si->si_szName) + 1 > sizeof(pfd->name)) {
		SetLastError(ERROR_BUFFER_OVERFLOW);
		goto done;
	}

	strcat(pfd->name, si->si_szName); // concat ":stream"

	if (phys_size) {
		pfd->size = si->si_phys_size;
	} else {
		pfd->size = si->si_size;
	}
	
done:
	return TRUE; // return of stream info (or main file info)
}
コード例 #9
0
ファイル: wcstold.c プロジェクト: mmcx/cegcc
  {
    if (IsDBCSLeadByte(*str))
	 str++;
    len++;
  }
  return len;
}
#endif

long double wcstold (const wchar_t * __restrict__ wcs, wchar_t ** __restrict__ wcse)
{
  char * cs;
  char * cse;
  unsigned int i;
  long double ret;
  const unsigned int cp = get_codepage ();

  /* Allocate enough room for (possibly) mb chars */
  cs = (char *) malloc ((wcslen(wcs)+1) * MB_CUR_MAX);

  if (cp == 0) /* C locale */
    {
      for (i = 0; (wcs[i] != 0) && wcs[i] <= 255; i++)
        cs[i] = (char) wcs[i];
      cs[i]  = '\0';
    }
  else
    {
      int nbytes = -1;
      int mb_len = 0;
      /* loop through till we hit null or invalid character */