Example #1
0
int main(const int argc, const char *argv[])
{
    char version_string[256];
    static struct s_hardware hardware;

    snprintf(version_string, sizeof version_string, "%s %s (%s)",
	     PRODUCT_NAME, VERSION, CODENAME);

    /* Cleaning structures */
    init_hardware(&hardware);

    /* Detecting Syslinux version */
    detect_syslinux(&hardware);

    /* Detecting parameters */
    detect_parameters(argc, argv, &hardware);

    /* Opening the Syslinux console */
    init_console(&hardware);

    /* Detect hardware */
    detect_hardware(&hardware);

    /* Clear the screen and reset position of the cursor */
    clear_screen();
    printf("\033[1;1H");

    more_printf("%s\n", version_string);

    int return_code = 0;

    if (!menumode || automode)
	start_cli_mode(&hardware);
    else {
	return_code = start_menu_mode(&hardware, version_string);
	if (return_code == HDT_RETURN_TO_CLI)
	    start_cli_mode(&hardware);
    }

    /* Do we got request to do something at exit time ? */
    if (strlen(hardware.postexec)>0) {
	    more_printf("Executing postexec instructions : %s\n",hardware.postexec);
	    runsyslinuxcmd(hardware.postexec);
    }

    return return_code;
}
Example #2
0
int start_menu_mode(struct s_hardware *hardware, char *version_string)
{
    struct s_hdt_menu hdt_menu;

    memset(&hdt_menu, 0, sizeof(hdt_menu));

    /* Setup the menu system */
    setup_menu(version_string);

    /* Compute all submenus */
    compute_submenus(&hdt_menu, hardware);

    /* Compute the main menu */
    compute_main_menu(&hdt_menu, hardware);

#ifdef WITH_MENU_DISPLAY
    t_menuitem *curr;
    char cmd[160];

    if (!quiet)
	more_printf("Starting Menu (%d menus)\n", hdt_menu.total_menu_count);
    curr = showmenus(hdt_menu.main_menu.menu);
    /* When we exit the menu, do we have something to do? */
    if (curr) {
	/* When want to execute something */
	if (curr->action == OPT_RUN) {
	    /* Tweak, we want to switch to the cli */
	    if (!strncmp
		(curr->data, HDT_SWITCH_TO_CLI, sizeof(HDT_SWITCH_TO_CLI))) {
		return HDT_RETURN_TO_CLI;
	    }
	    /* Tweak, we want to start the dump mode */
	    if (!strncmp
		(curr->data, HDT_DUMP, sizeof(HDT_DUMP))) {
		    dump(hardware);
	        return 0;
	    }
	    if (!strncmp
		(curr->data, HDT_REBOOT, sizeof(HDT_REBOOT))) {
		syslinux_reboot(1);
	    }
	    strcpy(cmd, curr->data);

	    /* Use specific syslinux call if needed */
	    if (issyslinux())
		runsyslinuxcmd(cmd);
	    else
		csprint(cmd, 0x07);
	    return 1;		// Should not happen when run from SYSLINUX
	}
    }
#endif
    return 0;
}
Example #3
0
/**
 * show_partition_information - print information about a partition
 * @ptab:	part_entry describing the partition
 * @i:		Partition number (UI purposes only)
 * @ptab_root:	part_entry describing the root partition (extended only)
 * @drive_info:	driveinfo struct describing the drive on which the partition
 *		is
 *
 * Note on offsets (from hpa, see chain.c32):
 *
 *  To make things extra confusing: data partition offsets are relative to where
 *  the data partition record is stored, whereas extended partition offsets
 *  are relative to the beginning of the extended partition all the way back
 *  at the MBR... but still not absolute!
 **/
static void show_partition_information(struct driveinfo *drive_info,
				       struct part_entry *ptab,
				       int partition_offset,
				       int nb_partitions_seen)
{
    char size[11];
    char bootloader_name[9];
    char *parttype;
    unsigned int start, end;

    int i = nb_partitions_seen;

    reset_more_printf();

    start = partition_offset;
    end = start + ptab->length - 1;

    if (ptab->length > 0)
	sectors_to_size(ptab->length, size);
    else
	memset(size, 0, sizeof size);

    if (i == 1)
	more_printf(" #  B       Start         End    Size Id Type\n");

    get_label(ptab->ostype, &parttype);
    more_printf("%2d  %s %11d %11d %s %02X %s",
		i, (ptab->active_flag == 0x80) ? "x" : " ",
		start, end, size, ptab->ostype, parttype);

    /* Extra info */
    if (ptab->ostype == 0x82 && swsusp_check(drive_info, ptab))
	more_printf("%s", " (Swsusp sig. detected)");

    if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0)
	more_printf("%-46s %s %s", " ", "Bootloader:", bootloader_name);

    more_printf("\n");

    free(parttype);
}
Example #4
0
//
// Get exhaustive info on the file.  Slow on network disks (avoid).
//
// Requires full canonical path (for UNC)
//
static int
_get_full_file_info(char *szFullPath, struct cache_entry *ce)
{
	HANDLE hFile;
	BY_HANDLE_FILE_INFORMATION bhfi;

	if (ce->ce_bGotFullInfo) {
		return 0;
	}

	ce->ce_bGotFullInfo = TRUE;

	if (gbReg) { // registry keys have no additional info
		return 0;
	}

	//
	// Open file with 0 access rights.
	//
	// FILE_FLAG_BACKUP_SEMANTICS is required to open directories
	// (not supported on Win9x)
	//
	if ((hFile = CreateFile(szFullPath,
			/*STANDARD_RIGHTS_READ | SYNCHRONIZE*/0,
			0, 0, OPEN_EXISTING,
			((ce->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ?
				FILE_FLAG_BACKUP_SEMANTICS : 0),
			0)) == INVALID_HANDLE_VALUE)  {
#ifdef DEBUG_FINDFIRST
more_printf("_get_full_file_info: CreateFile(%s) failed\n", szFullPath);
more_fflush(stdmore);
#endif
		MapWin32ErrorToPosixErrno();
		return -1;
	}

	memset(&bhfi, 0, sizeof(bhfi));

	if (!GetFileInformationByHandle(hFile, &bhfi)) {
		MapWin32ErrorToPosixErrno();
		CloseHandle(hFile);
		return -1;
	}

	CloseHandle(hFile);

	ce->dwVolumeSerialNumber = bhfi.dwVolumeSerialNumber;
	ce->nNumberOfLinks = bhfi.nNumberOfLinks;
	ce->ce_ino = _to_unsigned_int64(bhfi.nFileIndexLow, bhfi.nFileIndexHigh);

	return 0;
}
Example #5
0
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;
}
Example #6
0
static BOOL
_LookupReg(struct find_reg *fr, struct _finddatai64_t *pfd)
{
	char szClass[128];
	DWORD dwClassLen = 128;
	DWORD lErrCode;
	DWORD dwSize=0;
	DWORD dwLen=0, dwGotType=0;
	FILETIME ftWrite;

	pfd->attrib = 0;
	pfd->time_create = -1L; 
	pfd->time_access = _cached_now();
	pfd->time_write = -1L;
	pfd->size = 0;

	if (fr->fr_bRootKeys) {
		//
		// Enumerate root keys.  Must do by hand
		//
		pfd->attrib = FILE_ATTRIBUTE_DIRECTORY;

		if (fr->fr_bEof) {  // if singleton
			strcpy(pfd->name, "\\"); // synthetic root
			return TRUE;
		}
		
		switch (fr->fr_dwIndex) {
			case 0:
				strcpy(pfd->name, "HKLM");
				break;
			case 1:
				strcpy(pfd->name, "HKCU");
				break;
			case 2:
				strcpy(pfd->name, "HKU");
				break;
#ifdef UNDEFINED // dont walk by default because it is so huge
			case 3:
				strcpy(pfd->name, "HKCR");
				break;
#endif
			default:
				fr->fr_bEof = TRUE;
				::SetLastError(ERROR_NO_MORE_FILES);
				return FALSE;
		}
		fr->fr_dwIndex++;
		return TRUE;
	}

	if (fr->fr_hKey == NULL) { // if first time
		if (fr->fr_szKey == NULL) { // if no intermediate key
			fr->fr_hKey = fr->fr_hRoot; // use root
		} else { // open intermediate key
			DWORD dwAccess = KEY_READ;
			if (gbIsWindowsWOW64 && !gb32bit) {
				// Allow access to 64 bit keys
				dwAccess |= 0x0100; // KEY_WOW64_64KEY
			}
			if (_EnableSecurityPrivilege()) {
				dwAccess |= ACCESS_SYSTEM_SECURITY;
			}
			if ((lErrCode = ::RegOpenKeyExA(fr->fr_hRoot, fr->fr_szKey, 0,
					dwAccess, &fr->fr_hKey)) != ERROR_SUCCESS) {
				::SetLastError((DWORD)lErrCode);
				return FALSE;
			}
		}
		//
		// Get last-write time and class name
		//
		if ((lErrCode = ::RegQueryInfoKeyA(fr->fr_hKey, szClass, &dwClassLen,
				NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
				&ftWrite)) != 0) {
			::SetLastError((DWORD)lErrCode);
			return FALSE;
		}
		if (dwClassLen > 0) {
			fr->fr_szClass = xstrdup(szClass);
		}
		fr->fr_fd.attrib = FILE_ATTRIBUTE_DIRECTORY;
		fr->fr_fd.time_write = ConvertFileTimeToTimeT(&ftWrite);
		fr->fr_fd.time_create = fr->fr_fd.time_write; 
		fr->fr_fd.time_access = _cached_now();
		fr->fr_fd.size = 0;
		if (fr->fr_szKey != NULL) {
			//
			// strip to last component for returned name
			//
			LPCSTR sz;
			if ((sz = (char *)strrchr((unsigned char *)fr->fr_szKey, '\\')) != NULL) {
				++sz;
			} else {
				sz = fr->fr_szKey;
			}
			strcpy(fr->fr_fd.name, sz);
		} // otherwise use the original fd.name from PrepReg()

		// Note: Use "REG.EXE FLAGS hklm\software\XXX" to view ControlFlags

//#ifdef UNDEFINED
		NTSTATUS Status;

		if (IsWindowsXP) {
			if (DynaLoad("NTDLL.DLL", "NtQueryKey", (PPFN)&pfnNtQueryKey)) {
				//
				// Query the key flags
				// Available on Vista, possibly XP
				//
				// ControlFlags = REG_KEY_xxx
				//
				KEY_FLAGS_INFORMATION kfi;
				ULONG ulResultLen = sizeof(kfi);
				memset(&kfi, 0, sizeof(kfi));
				Status = (*pfnNtQueryKey)(fr->fr_hKey,
					KeyFlagsInformation,
					&kfi, sizeof(kfi), &ulResultLen);

#ifdef _DEBUG
if (fr->fr_szKey != NULL) {
more_printf("%s\n", fr->fr_szKey);
}
#endif
				if (NT_SUCCESS(Status)) {
#ifdef _DEBUG
more_printf("Wow64Flags=%08X, KeyFlags=%08X, ControlFlags=%08X\n",
kfi.Wow64Flags, kfi.KeyFlags, kfi.ControlFlags);
#endif
				}
				if (IsVista) {
					//
					// BUG: KeyVirtualizationInformation returns
					// all zeros for every key on Vista if not running
					// in virtual mode.
					//
					KEY_VIRTUALIZATION_INFORMATION kvi;
					ulResultLen = sizeof(kvi);
					memset(&kvi, 0, sizeof(kvi));
					Status = (*pfnNtQueryKey)(fr->fr_hKey,
						KeyVirtualizationInformation,
						&kvi, sizeof(kvi), &ulResultLen);
					if (NT_SUCCESS(Status)) {
						if (kvi.VirtualStore) {
							//
							// The key is mirrored.  Only when --virtual
							//
							fr->fr_fd.attrib |= FILE_ATTRIBUTE_VIRTUAL;
						}
#ifdef _DEBUG
more_printf("VirtualizationCandidate=%u, VirtualizationEnabled=%u\n",
	kvi.VirtualizationCandidate, kvi.VirtualizationEnabled);
more_printf("VirtualTarget=%u, VirtualStore=%u, VirtualSource=%u\n",
	kvi.VirtualTarget, kvi.VirtualStore, kvi.VirtualSource);
more_printf("Reserved=%08X\n", kvi.Reserved);
#endif
					}
				} // IsVista
#ifdef _DEBUG
more_printf("\n");
#endif
			}
		} // IsWindowsXP
//#endif // UNDEFINED
	} // if first time

	*pfd = fr->fr_fd; // struct copy

	LPCSTR szValue = fr->fr_szValue;

	if (szValue != NULL) {
		if (strcmp(szValue, "[default]") == 0) {
			szValue = "";
		}
		//
		// Query a single value - just check existance and get size
		//
		if ((lErrCode = ::RegQueryValueExA(fr->fr_hKey, szValue, 0,
				&dwGotType, NULL, &dwSize)) != ERROR_SUCCESS) {
			::SetLastError((DWORD)lErrCode);
			return FALSE;
		}
		pfd->size = dwSize; // 64 bit
		pfd->attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
		strcpy(pfd->name, szValue);
		return TRUE;
	}
	if (fr->fr_bEof) {
		//
		// Query a single key - already did above, so quit
		//
		return TRUE;
	}
	if (!fr->fr_bReturnedDot) {
		//
		// Return a synthetic dot "."
		// Required by dirent()
		//
		fr->fr_bReturnedDot = TRUE;
		strcpy(pfd->name, ".");
		pfd->attrib |= FILE_ATTRIBUTE_DIRECTORY;
		pfd->time_write = _cached_now();
		pfd->time_create = _cached_now();
		pfd->time_access = _cached_now();
		pfd->size = 0;
		return TRUE;
	}
	if (!fr->fr_bEnumValues) {
		//
		// Enumerate subkeys first
		//
		dwLen = FILENAME_MAX;
		if ((lErrCode = ::RegEnumKeyExA(fr->fr_hKey, fr->fr_dwIndex,
			pfd->name, &dwLen, NULL, NULL, NULL, &ftWrite)) != ERROR_SUCCESS) {
			if (lErrCode == ERROR_NO_MORE_ITEMS) {
				fr->fr_bEnumValues = TRUE;
				fr->fr_dwIndex = 0;
				goto enum_values;
			}
			::SetLastError((DWORD)lErrCode);
			return FALSE;
		}
		pfd->attrib |= FILE_ATTRIBUTE_DIRECTORY;
		//
		// The recursive call to _LookupReg() will determine the virtual status.
		//
		pfd->attrib &= ~FILE_ATTRIBUTE_VIRTUAL;
		pfd->time_write = ConvertFileTimeToTimeT(&ftWrite);
		pfd->time_create = fr->fr_fd.time_write; 
		pfd->time_access = _cached_now();
		pfd->size = 0;
		fr->fr_dwIndex++;
		return TRUE;
	}

enum_values:
	//
	// Enumerate values second
	//
	dwLen = FILENAME_MAX;
	dwSize = 0;
	if ((lErrCode = ::RegEnumValueA(fr->fr_hKey, fr->fr_dwIndex, pfd->name,
				&dwLen, NULL, NULL, NULL, &dwSize)) != ERROR_SUCCESS) {
		if (lErrCode == ERROR_NO_MORE_ITEMS) {
			fr->fr_bEof = TRUE;
			lErrCode = ERROR_NO_MORE_FILES; // expected by caller
		}
		if (lErrCode != ERROR_MORE_DATA) { // ok, because no data buf
			::SetLastError(lErrCode);
			return FALSE;
		}
	}

	pfd->attrib &= ~FILE_ATTRIBUTE_VIRTUAL;

	if (virtual_view && fr->fr_szKey != NULL && (fr->fr_fd.attrib & FILE_ATTRIBUTE_VIRTUAL)) {
		//
		// Query the virtual store to determine if the registry value is
		// really mirrored
		//
		// Open HKCU\Software\Classes\VirtualStore\Machine\SOFTWARE\xxx
		//
		LPSTR szVirtStore = (LPSTR)alloca(strlen(fr->fr_szKey) + 80);
		strcpy(szVirtStore, "Software\\Classes\\VirtualStore\\MACHINE\\");
		strcat(szVirtStore, fr->fr_szKey);

		HKEY hVirtKey= (HKEY)INVALID_HANDLE_VALUE;
		DWORD dwAccess = KEY_READ;

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

		//
		// DESIGN BUG: Querying HKCU\Classes\VirtualStore returns the merged
		// view when --virtual!
		//
		// WORKAROUND: Temporarily turn off virtual mode so we can inspect 
		// the actual HKCU\Classes\VirtualStore.
		//
		SetVirtualView(FALSE/*bEnable*/, FALSE/*bVerify*/);

		if ((lErrCode = ::RegOpenKeyExA(HKEY_CURRENT_USER, szVirtStore, 0,
				dwAccess, &hVirtKey)) == ERROR_SUCCESS) {
			DWORD dwValueLen=0;
			if (::RegQueryValueExA(hVirtKey, pfd->name, 0, NULL, NULL, &dwValueLen) == ERROR_SUCCESS) {
				//
				// Found the value in the VirtualStore
				//
				pfd->attrib |= FILE_ATTRIBUTE_VIRTUAL;
			}
			::RegCloseKey(hVirtKey);
		}
		//
		// Turn virtual mode back on
		//
		SetVirtualView(TRUE/*bEnable*/, FALSE/*bVerify*/);
	}

	if (pfd->name[0] == '\0') {
		strcpy(pfd->name, "[default]");
	}
	pfd->size = fr->fr_fd.size = dwSize;
	pfd->attrib &= ~FILE_ATTRIBUTE_DIRECTORY;
	// Use the key's timestamp for the value's timestamp
	pfd->time_create = fr->fr_fd.time_create;
	pfd->time_access = fr->fr_fd.time_access;
	pfd->time_write = fr->fr_fd.time_write;
	//fr->fr_fd.size = 0;

	fr->fr_dwIndex++;
	return TRUE;
}
Example #7
0
//
// 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; 
}
Example #8
0
//
// Opendir with wildcard pattern, for network speedup
//
// Called by glob.c
//
static DIR* 
__opendir_with_pat(const char* szPath, const char* szPat, BOOL bCache)
{
	char szBuf[FILENAME_MAX];
	char szFullDirPath[FILENAME_MAX];
	char szPatBuf[FILENAME_MAX+10];
	char* sz;
	struct cache_dir *cd;
	struct cache_entry *ce;
	DIR* pDir;
	long hFind;
	struct _finddatai64_t fd;
	BOOL bShowStreams = (show_streams == yes_arg);
	BOOL bFixedDisk = FALSE;
	BOOL bGetFullFileInfoOk = TRUE;

	//
	// Delete the previous non-cached dir, if any
	//
	if (_dir_nocache != NULL) {
		_delete_dir(_dir_nocache);
		_dir_nocache = NULL;
	}

	lstrcpyn(szBuf, szPath, sizeof(szBuf));
	//
	// Change forward slashes to backward slashes
	//
	for (sz = szBuf; *sz; ++sz) {
		if (*sz == '/') {
			*sz = '\\';
		}
	}
	//
	// Strip trailing backslashes
	//
	for (--sz; sz > szBuf; --sz) {
		if (*sz != '\\') {
			break;
		}
		if (sz == szBuf+2 && szBuf[1] == ':') {
			break; // stop if C:\  
		}
		*sz = '\0';
	}

	if (!gbReg) {
		//
		// See if the pattern contains any UNIX-style glob chars
		// other than *?
		//
		// Note that '!' is legal in an NTFS file name.
		//
		// Note that all glob chars are legal in registry names.
		//
		if (_mbspbrk(szPat, "[]+@") != NULL) {
			szPat = "*"; // punt
		}
	}

	//
	// Return cached dir if available
	//
	if ((cd = _find_cache_dir(szBuf, szPat)) != NULL) {
		pDir = xmalloc(sizeof(DIR));
		memset(pDir, 0, sizeof(pDir));
		pDir->dd_cd = cd;
		pDir->dd_next_entry = cd->cd_entry_first;
		return pDir;
	}

	//
	// Get the absolute path of the directory for FindFirst
	//
	if (_GetAbsolutePath(szBuf, szFullDirPath, FILENAME_MAX, &bFixedDisk) < 0) {
		return NULL;
	}

	//
	// Do not show streams if --fast on a non-fixed disk
	//
	if (run_fast && !bFixedDisk) {
		bShowStreams = FALSE;
	}

	//
	// See if the resulting path is too long
	//
	if (strlen(szBuf) + strlen(szPat) + 2 > sizeof(szBuf)) {
		errno = ENAMETOOLONG;
		return NULL;
	}

	//
	// Create a new directory node
	//
	cd = (struct cache_dir *)xmalloc(sizeof(struct cache_dir));
	memset(cd, 0, sizeof(*cd));
	cd->cd_dirname = xstrdup(szBuf); // *not* abs path - must match for caching
	cd->cd_pat = xstrdup(szPat);

	//
	// Append search pattern for FindFirstFile.
	// Use absolute path to make sure it works w/UNC
	//
	strcpy(szPatBuf, szFullDirPath);
	if (*right(szPatBuf, 1) != '\\') { // if not already
		strcat(szPatBuf, "\\");
	}
	strcat(szPatBuf, szPat);

#ifdef UNDEFINED
	//
	// BUG: FindFirst("\\server\share") fails!  Must append
	// a backslash, "\\server\share\"
	// 
	if (_IsServerRootPath(szPatBuf)) {
		sz = szPatBuf + strlen(szPatBuf) - 1;
		if (*sz != '\\') {
			*++sz = '\\';
			*++sz = '\0';
		}
	}
#endif

#ifdef _DEBUG
#define DEBUG_FINDFIRST
#endif
#ifdef DEBUG_FINDFIRST
more_printf("opendir: findfirst on \"%s\"\n", szPatBuf);
more_fflush(stdmore);
#endif

	//
	// Always guaranteed to return at least "." and "..", otherwise
	// not a directory or not found.
	//
	if ((hFind = _xfindfirsti64(szPatBuf, &fd, bShowStreams, DT_DIR))
			== (long)INVALID_HANDLE_VALUE) {
		MapWin32ErrorToPosixErrno();
		free(cd->cd_dirname);
		free(cd->cd_pat);
		free(cd);
		return NULL;
	}

	if (bCache) {
		//
		// Append new directory to the dir cache list
		//
		if (_dir_first == NULL) {
			_dir_first = _dir_last = cd;
		} else {
			_dir_last->cd_next = cd;
			_dir_last = cd;
		}
		_dir_nocache = NULL;
	} else {
		//
		// Save as non-cached
		//
		_dir_nocache = cd;
	}

	do {
		//
		// Append each file entry to the dir
		//
		ce = (struct cache_entry *)xmalloc(sizeof(*ce));
		memset(ce, 0, sizeof(*ce));
		if (cd->cd_entry_first == NULL) {
			cd->cd_entry_first = cd->cd_entry_last = ce;
		} else {
			cd->cd_entry_last->ce_next = ce;
			cd->cd_entry_last = ce;
		}
		ce->ce_filename = (char *)xstrdup(fd.name);
		ce->ce_size = fd.size;
		ce->ce_ino = 1; // requires GetFileInformationByHandle - uintmax_t
		ce->dwFileAttributes = fd.attrib; // FILE_ATTRIBUTE_NORMAL maps to 0
		ce->ce_atime = fd.time_access;
		ce->ce_mtime = fd.time_write;
		ce->ce_ctime = fd.time_create;
		ce->nNumberOfLinks = 1;

		if (bFixedDisk) {
			ce->dwFileAttributes |= FILE_ATTRIBUTE_FIXED_DISK;
		}

		// Flag reparse points and .LNK shortcuts as symbolic links
		if ((ce->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 ||
				_mbsicmp(right(fd.name, 4), ".lnk") == 0) {
			ce->ce_bIsSymlink = TRUE;
		}

		//
		// If we are reparse point, or need full info,
		// or phys size, or short names, or ls -l
		//
		if ((ce->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0
				|| gbReg || !run_fast || bFixedDisk || print_inode
				|| phys_size || short_names) {
			char szBuf2[FILENAME_MAX], szBuf3[FILENAME_MAX];
			//
			// Build dir\file
			//
			if (strlen(szFullDirPath) + strlen(fd.name) + 2 < sizeof(szBuf2)) {
				strcpy(szBuf2, szFullDirPath); // directory path
				if (*right(szBuf2, 1) != '\\') { // if not already
					strcat(szBuf2, "\\");
				}
				strcat(szBuf2, fd.name);
				//
				// Get the absolute path
				//
				if (_GetAbsolutePath(szBuf2, szBuf3, FILENAME_MAX, NULL) >= 0) {
					//
					// Squirrel away our abs path for later lookup by security.cpp
					//
					ce->ce_abspath = xstrdup(szBuf3);

					if (gbReg && (ce->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
						// For registry keys we must test each regkey explicitly
						_follow_symlink(ce);
					}

					if ((!run_fast || bFixedDisk || print_inode) &&
							bGetFullFileInfoOk) {
						//
						// Get inode and hardlink info
						// (requires absolute path)
						//
						bGetFullFileInfoOk = (_get_full_file_info(szBuf3, ce) == 0);
					}
				}
				//
				// Get the physical size too if requested
				//
				if (phys_size) {
					ce->ce_size = _get_phys_size(szBuf2, ce->ce_size);
				}

				if (short_names) {
					//
					// Get the short path, then extract the rightmost 
					// component and stuff it into ce->ce_filename
					//
					_get_short_path(szBuf2);
					if ((sz = strrchr(szBuf2, '\\')) != NULL) {
						++sz;
						free(ce->ce_filename);
						ce->ce_filename = (char *)xstrdup(sz);
					}
				}

			}
		}
	} while (_xfindnexti64(hFind, &fd, bShowStreams) != -1);

	if (GetLastError() != ERROR_NO_MORE_FILES) { // network fail during walk
		DWORD dwError = GetLastError();
		_xfindclose(hFind, bShowStreams);
		SetLastError(dwError);
		MapWin32ErrorToPosixErrno();
		return NULL;
	}

	if (_xfindclose(hFind, bShowStreams) == -1) {
		MapWin32ErrorToPosixErrno();
		return NULL;
	}

	//
	// Build and return DIR
	//
	pDir = xmalloc(sizeof(DIR));
	memset(pDir, 0, sizeof(pDir));
	pDir->dd_cd = cd;
	pDir->dd_next_entry = cd->cd_entry_first;
	return pDir;
}
Example #9
0
//
// Return the symlink if followable, otherwise return the current
// node again
//
static struct cache_entry *
_follow_symlink(struct cache_entry *ce)
{
	char *sz, *szFullPath;
	char szPath[FILENAME_MAX+10];
	struct cache_entry *symce;
	long hFind;
	struct _finddatai64_t fd;
	BOOL bFixedDisk = FALSE;

	if (!gbReg && !ce->ce_bIsSymlink) {
		// not a symlink
		return ce;
	}

	if (ce->ce_symlink != NULL) {
		return ce->ce_symlink; // return whatever we got earlier
	}

	if (ce->ce_bBadSymlink) {
		//
		// Already tried and failed
		//
		return ce;
	}

	ce->ce_bBadSymlink = TRUE; // provisionally mark as bad

	if (ce->ce_abspath == NULL) { // if earlier _ExpandPath failed
		return ce; // bail
	}

	if (gbReg) {
		if ((sz = _GetRegistryLink(ce, szPath)) == NULL) {
			return ce; // bail
		}
	} else if ((ce->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
		//
		// Query the reparse point
		//
		if ((sz = _GetReparseTarget(ce, szPath)) == NULL) {
			return ce; // bail
		}
	} else {
		//
		// Query the .LNK shortcut
		//
		if ((sz = _GetShortcutTarget(ce, szPath)) == NULL) {
			return ce; // bail
		}
	}

	if (!gbReg && short_names) {
		_get_short_path(sz); // update in place
	}

	//
	// Build the symbolic link cache_entry
	//
	symce = (struct cache_entry *)xmalloc(sizeof(*symce));
	memset(symce, 0, sizeof(*symce));
	//
	// Store relative path for later readlink() (not just last component)
	//
	symce->ce_filename = (char *)xstrdup(sz);
	ce->ce_symlink = symce; // point to symlink
	ce->ce_bIsSymlink = TRUE;
	symce->ce_ino = 1; // requires GetFileInformationByHandle - uintmax_t
	symce->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; // we know this..
	symce->nNumberOfLinks = 1;

	//
	// Errors after this point are not very important.  At worst
	// we might lose st_mode, st_size and st_time info.
	//

	ce->ce_bBadSymlink = FALSE; // link is ok


	//
	// Get the absolute path
	//
	if (_GetAbsolutePath(symce->ce_filename, szPath, FILENAME_MAX, &bFixedDisk) < 0) {
		return symce; // bail
	}

	//
	// Squirrel away the absolute path for security.cpp
	//

	// BUG? should be symce->ce_abspath = xstrdup(szPath); ??
	ce->ce_abspath = xstrdup(szPath);

	if (gbReg) {
		return symce; // done 
	}

	szFullPath = szPath;

#ifdef DEBUG_FINDFIRST
more_printf("_follow_symlink: findfirst on \"%s\"\n", szFullPath);
more_fflush(stdmore);
#endif

	//
	// Do a singleton FindFirst to get WIN32_FILE_DATA
	//
	if ((hFind = _xfindfirsti64(szFullPath, &fd,
			FALSE/*bShowStreams*/, DT_UNKNOWN)) != (long)INVALID_HANDLE_VALUE) {
		// Suceeded
		if (_xfindclose(hFind, FALSE/*bShowStreams*/) == -1) {
			MapWin32ErrorToPosixErrno();
			return symce; // bail
		}
	} else {
		//
		// FindFirst failed.  This is a normal error (sic) for root folders
		// e.g., C:\ and sometimes \\server\share\
		//
		if ((szFullPath[1] == ':' && szFullPath[2] == '\\' && szFullPath[3] == '\0') ||
				_IsServerRootPath(szFullPath)) {
			//
			// Fake an entry for the root folder
			//
			time_t t;
			memset(&fd, 0, sizeof(fd));
			t = time(0);
			fd.attrib = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM;
			strcpy(fd.name, "\\");
			fd.time_access = t;
			fd.time_write = t;
			fd.time_create = t;
		} else {
			MapWin32ErrorToPosixErrno();
			return symce;
		}
	}

	//
	// Fill in more data for the symlink target
	//
	symce->ce_size = fd.size;
	symce->dwFileAttributes = fd.attrib; // FILE_ATTRIBUTE_NORMAL maps to 0
	symce->ce_atime = fd.time_access;
	symce->ce_mtime = fd.time_write;
	symce->ce_ctime = fd.time_create;

	if (bFixedDisk) {
		symce->dwFileAttributes |= FILE_ATTRIBUTE_FIXED_DISK;
	}

	// Flag reparse points and .LNK shortcuts as symbolic links
	if ((symce->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 ||
			_mbsicmp(right(fd.name, 4), ".lnk") == 0) {
		symce->ce_bIsSymlink = TRUE; // symlink pointing to a symlink (rare)
	}

	if (phys_size) {
		symce->ce_size = _get_phys_size(szFullPath, symce->ce_size);
	}

	//
	// Tah dah!
	//
	ce->ce_bBadSymlink = FALSE;

	return symce;
}
Example #10
0
static int
__xstat(const char *szPath, struct xstat *st, 
	unsigned long dwType, BOOL bCache, BOOL bFollowSymlink)
{
	char szFullPath[FILENAME_MAX], szBuf[FILENAME_MAX];
	char szDirBuf[FILENAME_MAX];
	char *sz, *szDir, *szFile;
	struct cache_dir *cd;
	struct cache_entry *ce;
	long hFind;
	struct _finddatai64_t fd;
	BOOL bShowStreams = (show_streams == yes_arg);
	BOOL bFixedDisk = FALSE; 

	lstrcpyn(szFullPath, szPath, FILENAME_MAX);
	//
	// Change forward slashes to backward slashes
	//
	for (sz = szFullPath; *sz; ++sz) {
		if (*sz == '/') {
			*sz = '\\';
		}
	}
	//
	// Strip trailing backslashes
	//
	for (--sz; sz > szFullPath; --sz) {
		if (*sz != '\\') {
			break;
		}
		if (sz == szFullPath+2 && szFullPath[1] == ':') {
			break; // stop if C:\  
		}
		*sz = '\0';
	}

	//
	// No FindFile wildcards allowed at this point
	//
	if (_mbspbrk(szFullPath, "?*") != NULL) {
		errno = ENOENT;
		return -1;
	}

	//
	// Break off dir and file components
	//
	strcpy(szBuf, szFullPath);

	if ((sz = strrchr(szBuf, '\\')) == NULL) {
		if (szBuf[1] == ':') {
			if (szBuf[2] == '\0') {
				// ls C:
				szDir = szBuf; // C:
				szFile = ".";
			} else {
				// ls C:foo
				szDirBuf[0] = szBuf[0];
				szDirBuf[1] = szBuf[1];
				szDirBuf[2] = '\0';
				szDir = szDirBuf; // C:
				szFile = szBuf+2; // foo
			}
		} else {
			// ls foo
			szDir = ".";
			szFile = szBuf;
		}
	} else {
		// ls dir\foo
		szFile = sz+1;
		//
		// Strip trailing backslashes from the dir component
		//
		strcpy(szDirBuf, szBuf); // copy to avoid stomping on szFile
		szDir = szDirBuf;
		sz = szDir + (sz-szBuf);
		*(sz+1) = '\0'; // ensure termination
		for (; *sz == '\\' && sz > szDirBuf; --sz) {
			if (sz == szDirBuf+2 && szDirBuf[1] == ':') {
				break; // stop if C:\  
			}
			*sz = '\0';
		}
	}

	if ((cd = _find_cache_dir(szDir, szFile)) != NULL) {
		//
		// Found hit from previous opendir()/readdir()
		//
		for (ce = cd->cd_entry_first; ce; ce = ce->ce_next) {
			if (ce->ce_filename[0] == szFile[0] &&
					_mbsicmp(ce->ce_filename, szFile) == 0) {
				//
				// Found file 
				//
				goto cache_hit;
			}
		}
		errno = ENOENT;  // not in cache dir
		return -1;
	}

	//
	// Get the canonical path for use in security.cpp
	//
	if (_GetAbsolutePath(szFullPath, szBuf, FILENAME_MAX, &bFixedDisk) < 0) {
		return -1;
	}

	strcpy(szFullPath, szBuf);

	//
	// Check the partial stat cache against the abs path
	//
	for (ce = _stat_first; ce; ce = ce->ce_next) {
		if (ce->ce_abspath && _mbsicmp(ce->ce_abspath, szFullPath) == 0) {
			goto cache_hit;
		}
	}

	//
	// Do not show streams if --fast on a non-fixed disk
	//
	if (run_fast && !bFixedDisk) {
		bShowStreams = FALSE;
	}

#ifdef DEBUG_FINDFIRST
more_printf("stat: findfirst on \"%s\"\n", szFullPath);
more_fflush(stdmore);
#endif

	//
	// Do a singleton FindFirst to get WIN32_FILE_DATA
	//
	if ((hFind = _xfindfirsti64(szFullPath, &fd, bShowStreams, dwType)) 
			!= (long)INVALID_HANDLE_VALUE) {
		// Succeeded
		if (_xfindclose(hFind, bShowStreams) == -1) {
			MapWin32ErrorToPosixErrno();
			return -1;
		}
	} else {
		//
		// FindFirst failed.  This is a normal (sic) error for root folders
		// e.g., C:\ and sometimes \\server\share\
		//
		if ((szFullPath[1] == ':' && szFullPath[2] == '\\' && szFullPath[3] == '\0') ||
				_IsServerRootPath(szFullPath)) {
			//
			// Fake an entry for the root folder
			//
			time_t t;
			memset(&fd, 0, sizeof(fd));
			t = time(0);
			fd.attrib = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM;
			strcpy(fd.name, "\\");
			fd.time_access = t;
			fd.time_write = t;
			fd.time_create = t;
		} else {
			MapWin32ErrorToPosixErrno();
			return -1;
		}
	}

	ce = (struct cache_entry *)xmalloc(sizeof(*ce));
	memset(ce, 0, sizeof(*ce));

	if (bCache) {
		//
		// Put on the partial stat cache
		//
		if (_stat_first == NULL) {
			_stat_first = _stat_last = ce;
		} else {
			_stat_last->ce_next = ce;
			_stat_last = ce;
		}
	}

	if (short_names) {
		_get_short_path(szFullPath); // update in place
	}
	ce->ce_filename = (char *)xstrdup(fd.name); // last component only
	ce->ce_size = fd.size;
	ce->ce_ino = 1; // requires GetFileInformationByHandle - uintmax_t
	ce->dwFileAttributes = fd.attrib; // FILE_ATTRIBUTE_NORMAL maps to 0
	ce->ce_atime = fd.time_access;
	ce->ce_mtime = fd.time_write;
	ce->ce_ctime = fd.time_create;
	ce->nNumberOfLinks = 1;
	if (bFixedDisk) {
		ce->dwFileAttributes |= FILE_ATTRIBUTE_FIXED_DISK;
	}

	//
	// Squirrel away the canonical path
	//
	ce->ce_abspath = xstrdup(szFullPath);

	// Flag reparse points and .LNK shortcuts as symbolic links
	if ((ce->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 ||
			_mbsicmp(right(fd.name, 4), ".lnk") == 0) {
		ce->ce_bIsSymlink = TRUE;
	}

	if (phys_size) {
		ce->ce_size = _get_phys_size(szFullPath, ce->ce_size);
	}
	if (!run_fast || bFixedDisk || print_inode) {
		//
		// Get inode and hardlink info
		//
		_get_full_file_info(szFullPath, ce);
	}

cache_hit:
	if (bFollowSymlink) {
		ce = _follow_symlink(ce);
	}
	memset(st, 0, sizeof(*st));
	st->st_ino = ce->ce_ino;
	st->st_size = ce->ce_size;
	st->st_atime = ce->ce_atime;
	st->st_mtime = ce->ce_mtime;
	st->st_ctime = ce->ce_ctime;
	st->st_nlink = (short)ce->nNumberOfLinks;
	st->st_mode = _MapMode(ce);
	st->st_ce = ce;

	return 0;
}
Example #11
0
/**
 * dump - dump info
 **/
void dump(struct s_hardware *hardware)
{
    if (hardware->is_pxe_valid==false) {
	    printf("PXE stack was not detected, Dump feature is not available\n");
	    return;
    }

    const union syslinux_derivative_info *sdi = syslinux_derivative_info();
    int err=0;
    ZZJSON *json = NULL;
    ZZJSON_CONFIG config = { ZZJSON_VERY_STRICT, NULL,
		(int(*)(void*)) fgetc,
		NULL,
		malloc, calloc, free, realloc,
		stderr, NULL, stdout,
		(int(*)(void *,const char*,...)) dumpprintf,
		(int(*)(int,void*)) fputc 
    };

    memset(&p_buf,0,sizeof(p_buf));

    /* By now, we only support TFTP reporting */
    upload=&upload_tftp;
    upload->name="tftp";

    /* The following defines the behavior of the reporting */
    char *arg[64];
    char filename[512]={0};
    compute_filename(hardware, filename, sizeof(filename));

    /* The filename */
    arg[0] = filename;
    /* The server to upload the file */
    if (strlen(hardware->tftp_ip) != 0) {
	    arg[1] = hardware->tftp_ip;
	    arg[2] = NULL;
    } else {
	    arg[1] = NULL;
	    snprintf(hardware->tftp_ip, sizeof(hardware->tftp_ip),
			    "%u.%u.%u.%u",
			    ((uint8_t *)&sdi->pxe.ipinfo->serverip)[0],
			    ((uint8_t *)&sdi->pxe.ipinfo->serverip)[1],
			    ((uint8_t *)&sdi->pxe.ipinfo->serverip)[2],
			    ((uint8_t *)&sdi->pxe.ipinfo->serverip)[3]);

    }

    /* We initiate the cpio to send */
    cpio_init(upload,(const char **)arg);

    dump_cpu(hardware, &config, &json);
    dump_pxe(hardware, &config, &json);
    dump_syslinux(hardware, &config, &json);
    dump_vpd(hardware, &config, &json);
    dump_vesa(hardware, &config, &json);
    dump_disks(hardware, &config, &json);
    dump_dmi(hardware, &config, &json);
    dump_memory(hardware, &config, &json);
    dump_pci(hardware, &config, &json);
    dump_acpi(hardware, &config, &json);
    dump_kernel(hardware, &config, &json);
    dump_hdt(hardware, &config, &json);

    /* We close & flush the file to send */
    cpio_close(upload);

    if ((err=flush_data(upload)) != TFTP_OK) {
	/* As we manage a tftp connection, let's display the associated error message */
	more_printf("Dump failed !\n");
	more_printf("TFTP ERROR on  : %s:/%s \n",hardware->tftp_ip, filename);
	more_printf("TFTP ERROR msg : %s \n",tftp_string_error_message[-err]);
    } else {
	more_printf("Dump file sent at %s:/%s\n",hardware->tftp_ip, filename);
    }
}
Example #12
0
void main_show_disk(int argc, char **argv, struct s_hardware *hardware)
{
    if (!argc) {
	more_printf("Which disk?\n");
	return;
    }

    int drive = strtol(argv[0], (char **)NULL, 16);

    if (drive < 0x80 || drive >= 0xff) {
	more_printf("Invalid disk: %d.\n", drive);
	return;
    }

    int i = drive - 0x80;
    struct driveinfo *d = &hardware->disk_info[i];
    char disk_size[11];
    char mbr_name[50];

    reset_more_printf();

    if (!hardware->disk_info[i].cbios) {
	more_printf("No disk found\n");
	return;			/* Invalid geometry */
    }

    get_mbr_string(hardware->mbr_ids[i], &mbr_name, 50);

    if ((int)d->edd_params.sectors > 0)
	sectors_to_size((int)d->edd_params.sectors, disk_size);
    else
	memset(disk_size, 0, sizeof disk_size);

    more_printf("DISK 0x%X:\n"
		"  C/H/S: %d cylinders, %d heads, %d sectors/track\n"
		"    EDD: Version: %X\n"
		"         Size: %s, %d bytes/sector, %d sectors/track\n"
		"         Host bus: %s, Interface type: %s\n"
		"    MBR: %s (id 0x%X)\n\n",
		d->disk,
		d->legacy_max_cylinder + 1, d->legacy_max_head + 1,
		d->legacy_sectors_per_track, d->edd_version, disk_size,
		(int)d->edd_params.bytes_per_sector,
		(int)d->edd_params.sectors_per_track,
		remove_spaces((char *)d->edd_params.host_bus_type),
		remove_spaces((char *)d->edd_params.interface_type), mbr_name,
		hardware->mbr_ids[i]);
    display_line_nb += 6;

    if (parse_partition_table(d, &show_partition_information)) {
	if (errno_disk) {
	    fprintf(stderr, "I/O error parsing disk 0x%X\n", d->disk);
	    get_error("parse_partition_table");
	} else {
	    fprintf(stderr, "Disk 0x%X: unrecognized partition layout\n",
		    d->disk);
	}
	fprintf(stderr, "\n");
    }

    more_printf("\n");
}