继这个问题和这一次,我问最近,但没有正确的细节......,最后这一次,我在自由帕斯卡论坛问具体....
任何人都可以向我提供指导,示例或某个地方的链接,解释如何使用Free Pascal调用物理连接的硬盘列表,或者,无论如何,Delphi,无论磁盘是否已由操作系统安装或不?我想要实现的屏幕截图中显示了一个示例(此屏幕截图中显示的是另一个软件产品).因此,拉出逻辑卷列表(C:\,E:\ etc)并不是我想要做的.如果磁盘有一个操作系统无法挂载的文件系统,我仍然希望看到列出的物理磁盘.
我强调C\C++\C夏普的例子很丰富,但不是我追求的.我主要需要Free Pascal示例,或者说,失败了,Delphi.

我在处理逻辑驱动器时遇到了一些问题.为清楚起见,无论分区如何,我对"物理磁盘"(PD)的定义都是原始磁盘."逻辑驱动器"(LD)指的是诸如驱动器E:,驱动器F:等的卷.
使用RRUZ(我的英雄SO成员)中的示例并实现WMI类我已经创建了一个用于读取磁盘的Freepascal程序.我通过\.\ PhyscialDiskX解决了PD问题,RRUZ(这里)创建的示例工作得很好.我可以读取PD的所有字节没有问题.
我对逻辑卷使用相同的句柄技术,它是\?\ E:或\?\ F:等.然后我使用IOCTL_DISK_GET_LENGTH_INFO来获取PD或LV的长度,然后读取字节范围,直到ReadBytes = TotalLength.我在MSDN网站上看到,它将自动检索传递的任何设备句柄的大小 - PD或LD都一样.事实上,我已经检查了我的程序returnzt WinHex,FTK Imager,HxD和其他几个低级磁盘工具返回的szie值.除了由0或1个起始位置引起的1字节差异外,它们匹配.
但是,出于某种原因,我的程序无法在Windows 7 Pro 64位上获得最终的32Kb,尽管以管理员身份运行该程序.它读取整个磁盘,然后读取最终缓冲区(以64Kb缓冲区完成)BytesRead返回-1.使用调试器我计算出以下值:
493,846,527 exact LV size of Drive F:
493,813,760 total bytes read at time of failure
32,767 bytes missing
Run Code Online (Sandbox Code Playgroud)
结果如下
BytesRead := FileRead(hDiskHandle, Buffer, (DiskSize - TotalBytesRead));
Run Code Online (Sandbox Code Playgroud)
在最终缓冲区读取时为-1.这是测试磁盘末尾的行,通过说"如果剩余读取的数量小于缓冲区大小的大小,则只尝试读取剩余的内容".因此,FileRead最后要求存储的字节值为32,767(因为此时的DiskSize - TotalBytesRead为32,767,这意味着要读取磁盘的剩余字节数).指定大小的缓冲区为64Kb.我的理解是你可以减少缓冲区而不是更多(FileRead状态:" 缓冲区必须至少是Count字节长.不执行检查 "?这是正确的吗?如果不是那么这可能是(也可能是)这个问题.
我不知道是不是因为IOCTL_DISK_GET_LENGTH_INFO,缓冲存储还是别的什么?希望有人能帮忙吗?我还在Lazarus Freepascal论坛上贴了一些截图.这是我的相关代码部分:
手柄:
// Create handle to source disk. Abort if fails
hSelectedDisk := CreateFileW(PWideChar(SourceDevice), FILE_READ_DATA,
FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, …Run Code Online (Sandbox Code Playgroud) 我不敢相信我为此付出了很多努力!希望这是一件容易的事。使用Delphi或Freepascal:
Given the whole integer value "1230", or "1850", how do you format that as a floating point string of 3 digits where the decimal is in the 3rd position, and the trailing digit discarded.
Example
1230 means "v12.3" 1850 means "v18.5"
So I need to convert the first two digits to a string. Then insert a decimal place. Convert the third digit to a string after the decimal place. And discard the zero. I've looked at Format, FormatFloat, Format, …
在Free Pascal库中,有一个哈希库,可以使用MD5和SHA1哈希算法(http://wiki.freepascal.org/hash).但是如果我想使用更高的一个,例如SHA256或SHA512呢?我可以使用Free Pascal实现这一目标吗?搜索FP Wiki重新调整SHA256\SHA512的零点击率.
我在Lazarus编程论坛上询问如何打开物理磁盘.我想允许用户在单击"选择磁盘"按钮时从系统中选择物理磁盘.Stack Overflow中有一些类似但不完全相同的示例(例如Delphi - 使用DeviceIoControl传递IOCTL_DISK_GET_LENGTH_INFO来获取闪存介质的物理大小(非分区)).
有很多C和C++使用的例子CreateFile(在文档中,特别是调用的例子DeviceIoControl)但我找不到任何Free Pascal或Delphi,我还不够好,我还没有找到如何做到这一点.
任何人都可以指向我解释它的链接的方向或更好仍然是用Delphi或Free Pascal编写的实际示例?任何人都可以帮我理解如何使用它吗?
平台:Lazarus 1.1,FreePascal 2.7.1,Win 7 32位.
我有一个字符串值如下:
FileName[12345][45678][6789].jpg
Run Code Online (Sandbox Code Playgroud)
默认情况下(假设这是默认行为0),我的程序当前从最后一对方括号中取出最后一组数字到文件名的最右边,即6789.它使用以下代码:
if chkbxOverrideUniqueID.Checked then
IDOverrideValue := StrToInt(edtToggleValue.Text);
// User is happy to find the right most unique ID
if not chkbxOverrideUniqueID.Checked then
LastSquareBracket := RPos(']', strFileName);
PreceedingSquareBracket := RPosEx('[', strFileName, LastSquareBracket) + 1;
strFileID := AnsiMidStr(strFileName, PreceedingSquareBracket, LastSquareBracket - PreceedingSquareBracket)
else // User doesn't want to find the rightmost ID.
// and now I am stuck!
Run Code Online (Sandbox Code Playgroud)
但是,我现在为用户添加了一个指定非默认行为的选项.例如,如果他们输入'1',则表示"从最右边的ID中查找第一个ID".例如[45678],因为[6789]是默认行为0,请记住.如果他们输入2,我希望它找到[12345].
我的问题:我如何调整上述代码才能实现这一目标?
我需要解析 RAM 转储以获取MFT记录(来自NTFS文件系统)。
我过去做过一些关于读取多个文件的标头(使用 FileSearcher 类等)的编程,但我不完全确定如何从大文件的开头开始读取,通读它,然后当找到某个值时,我需要从找到魔术值的点开始读取 1024 个字节(FILE0在 MFT 条目的情况下),并使用该值和 1024 字节范围末尾之间的值进行“操作” 。然后它需要继续搜索下一个FILE0记录。
到目前为止,我有以下内容 - 我的意图是它读取源文件(这是一个 TFileStream)以查找“FILE0”。当它找到它时,在这个阶段我只想报告它已经找到一条记录并输出位置,但在适当的时候我需要它从找到 FILE0 的点读取一系列字节:
type
MFTRecordsStore = packed record
FILE0MagicMarker: array[0..4] of byte;
// Lots more follow....
end;
var
MFTHeaderArray : MFTRecordsStore;
FILE0Present : string;
i : integer;
begin
SourceFile.Position := 0;
while (SourceFile.Position < SourceFile.Size) do
begin
SourceFile.ReadBuffer(MFTHeaderArray, SizeOf(MFTHeaderArray));
for i := 0 to 4 do
FILE0Present := FILE0Present + IntToHex(MFTHeaderArray.FILE0MagicMarker[i], 2);
if FILE0Present = 'FILE0' …Run Code Online (Sandbox Code Playgroud) 使用FreePascal(或Delphi,如果没有FP示例),给定一个2048字节的缓冲区作为"字节数组",如何在缓冲区中搜索"StringA"?
var
Buffer : array[1..2048] of byte;
...
repeat
i := 0;
BlockRead(SrcFile, Buffer, SizeOf(Buffer), NumRead);
// Now I want to search the buffer for "StringA"?
...
Run Code Online (Sandbox Code Playgroud)
谢谢
继这个回答的问题,我有另一个棘手的问题.我的编码是Free Pascal,但Delphi解决方案可能会起作用.
简而言之,我有一个串联路径的字符串值,它是通过获取源目录并在目标目录中重新创建该树而形成的.例如
C:\ SourceDir\SubDirA变为F:\ DestinationDir\SourceDir\SubDirA.
但是,我对我的程序的Linux版本的解决方案(如上面的链接中所述)与Windows版本不兼容,因为我最终得到:
F:\ DestionationDir\C:SourceDir\SubDirA.
这是无效的.
所以我想出了这个"仅在Windows中运行"代码来删除重组路径的中央驱动器号,但是在开头留下最初的一个,说"从左边的第4个字符开始查看字符串.如果你找到'C:',删除它",使路径变为F:\ DestinationDir\SourceDir\SubDirA.
{$IFDEF Windows} // Only do this for the Windows version
k := posex('C:', FinalisedDestDir, 4); // Find 'C:' in the middle of the concatanated path and return its position as k
Delete(FinalisedDestDir, k, 2); // Delete the 2 chars 'C:' of 'C:\' if found, leaving the '\' to keep the path valid
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
现在,如果C:是所选目录的源,那就可以正常工作.但显然如果用户正在从另一个驱动器复制数据(例如E:,F:,G:或其他任何驱动器直到Z :)它将无法工作.
所以我的问题是,如何对其进行编码,使其显示"如果在左边第4个字符后找到任何驱动器号a:到z:,则将其删除"?虽然任何解决方案都"有效",但理想情况下我需要快速解决方案.最好的解决方案是首先没有它在那里,但鉴于我在回复我之前的帖子时发布的解决方案,由于我用来形成的程序,我无法弄清楚如何不使用它它.
我不想让人们解释为什么以及怎么这样我才会跳进去.
我有一个包含原始字节数据的字节数组.该数组是1000个字节.我想通过1000字节的数组并仅提取可能类似于文件名的UTF-16 Unicode字符,但我不知道字符出现在1000字节数组中的确切位置.
我已经阅读了 Lazarus Unicode Page和这个,但我仍然不确定我的问题的语法方法.我知道Unicode字符大小最多可达4个字节,但通常是两个(字母和空格).
我已经使用UTF8encode(WideCharLenToString(@ MyArray,SomeIntValue)成功用于其他领域,我知道某些Unicode字符存在于我询问的这个线程中并且现在已经解决了.但我现在需要为它们"寻找"它们,因为一个不同的原因,在数组中.例如" 查看前16个字节.它们是Unicode吗?如果没有,请查看下一个16.它们是Unicode吗?如果是,请将它们转换为字符串并显示它们".
谁能帮我?
我用Free Pascal和Lazarus IDE编写了一个程序.简而言之,它递归扫描每个文件的目录和'做东西'(散列),然后将散列值和文件名输出到StringGrid中,并使用每个连续文件刷新.
它适用于多达几千个文件,但是当你达到数万个时,它确实变慢,每半秒处理一个文件,即使它只是一个几Kb的小文件.
责任代码的主要部分如下.任何人都可以看到为什么我的程序在网格中的文件数量超过数万时会变慢?
procedure TForm1.HashFile(FileIterator: TFileIterator);
var
SizeOfFile : int64;
NameOfFileToHash, fileHashValue, PercentageProgress : string;
FI : TFileIterator; //File Iterator class
SG : TStringGrid;
begin
FI := TFileIterator.Create;
SG := TStringGrid.Create(self);
SizeOfFile := 0;
fileHashValue := '';
if StopScan = FALSE then // If Stop button clicked, cancel scan
begin
NameOfFileToHash := (FileIterator.FileName);
SizeOfFile := FileSize(NameofFileToHash);
StatusBar1.SimpleText := 'Currently Hashing: ' + NameOfFileToHash;
fileHashValue := CalcTheHashFile(NameOfFileToHash); // Custom function, see below
// Now lets update the stringgrid and …Run Code Online (Sandbox Code Playgroud) 我的程序的一部分从char类型的缓冲区读取ASCII文本,它本身可以包含一些不可打印的非ASCII垃圾.当显示这些区域时,例如in ShowMessage(strVar),如果有空字符(0x00),则不显示该字符串,即使其中有可打印文本也是如此.
所以我写了这个小函数(我试图养成为这些技巧编写函数的习惯,但仍然不是很擅长)来清理任何不可打印的空字符的变量:
// FUNCTION RemoveNullChars : Removes 0x00 from strings, which cause empty string
// fields if not removed sometimes
function TForm1.RemoveNullChars(strValue: string): String;
var
i : integer;
NullChar : char;
begin
NullChar := Chr($00);
for i := 0 to Length(strValue) do
begin
if strValue[i] = NullChar then
strValue[i] := ' ';
end;
result := strValue;
end;
Run Code Online (Sandbox Code Playgroud)
它编译好,实际上在一些缓冲段上工作......它确实剥离了空格,但并不总是如此.其他时候,使用不同的数据源(但时间类型的数据源),我收到此错误:

我无法弄清楚为什么它编译好然而实际上对某些数据运行正常但对其他数据没有效果?