Delphi翻译Api头文件时的一个坑

typedef enum _EVT_RENDER_FLAGS
{
    EvtRenderEventValues = 0,           // Variants
    EvtRenderEventXml,                  // XML
    EvtRenderBookmark                   // Bookmark

 } EVT_RENDER_FLAGS;
  EVT_RENDER_FLAGS = (EvtRenderEventValues = 0,
    EvtRenderEventXml = 1,
    EvtRenderBookmark = 2);


DWORD      Flags    //Windows SDK的定义

翻译成Delphi的时候一定也要定义成对应的数据类型千万别

Flags:EVT_RENDER_FLAGS;

不然 32Bit的时候正常 但是64Bit程序的时候 sizeof(EVT_RENDER_FLAGS)  =  1

记一笔manifest与dpiAware

<application xmlns="urn:schemas-microsoft-com:asm.v3">    
<windowsSettings>    
<!-- Per Monitor V1 [OS >= Windows 8.1]     
         Values: False, True, Per-monitor, True/PM -->    
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">    
true/PM</dpiAware>    
<!-- Per Monitor V1 [OS >= Windows 10 Anniversary Update (1607, 10.0.14393, Redstone 1)]    
         Values: Unaware, System, PerMonitor -->    
<!-- Per Monitor V2 [OS >= Windows 10 Creators Update (1703, 10.0.15063, Redstone 2)]    
         Value: PerMonitorV2 -->    
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">    
PerMonitorV2, PerMonitor</dpiAwareness>    
</windowsSettings>    
</application>

或者直接禁用掉

  <asmv3:application>
    <asmv3:windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">unaware</dpiAwareness>
    </asmv3:windowsSettings>
  </asmv3:application>


梅林{merlin} 基于wpa_supplicant得802.1X PEAP认证

在公司需要用网线得设备有点多而且需要相互之间进行互联传输

但是网络做了规则内网不能互相连通,而且桌子上只有一个网线口可以用,

所以整了个二手AC3100,merlin刷上entware装好


1.先保存好配置文件

ctrl_interface=/opt/var/run/wpa_supplicant
ctrl_interface_group=wheel
update_config=1
network={
	key_mgmt=IEEE8021X
	eap=PEAP
	phase2="auth=MSCHAPV2"
	identity="username"
	password="password"
	eapol_flags=0
}


2.然后再来个脚本然后扔到/opt/etc/init.d/  改成S数字* {entware 会开机运行rc.unslung 这个脚本会执行所有S数字开头得脚本}

#!/bin/sh
ifconfig eth0 down
sleep 1
wpa_supplicant -B -i eth0 -c /opt/etc/eap.conf -D wired
ifconfig eth0 up
udhcpc -i eth0 -b

PS:-i 指定网口 -D 指定类型 我这里是有线连所以 wired 

脚本流程就是先关掉wan口 然后wpa_supplicant设置再开启wan口

最后再手动dhcpclient获取下IP


记几个最近写代码遇到的几个坑。

  1. 虽然Windows Api会对 C:\\Windows\\  这种双斜杠的路径做兼容处理,但是Explorer.exe并不会,在地址栏中输入C:\\这种路径是会报错的,所以explorer.exe /e,/select,文件路径 的时候一定要做下处理。

  2. 这个算是自己的坑,多线程\线程池的时候不要直接CPUCount * 2 - 1,一定要判断一下最后的的值再说。

  3. DLL HiJack可能会被杀软影响运行。

Delphi 使用Windows API(WinCrypt)计算文件MD5哈希,支持大文件

Delphi_WinApi_GetFileHash4MD5.jpg/


Delphi 默认没有WinCrypt相关函数的定义所以引用JwaWinCrypt{jedi-apilib}单元

将 CryptCreateHash(hProv, CALG_MD5,0, 0, hHash)中的参数CALG_MD5

修改为CALG_SHA1即为计算SHA1哈希 值得注意的时CALG_SHA_256,CALG_SHA_384,CALG_SHA_512

着三个算法是在Windows XP SP3才开始支持的  XP SP2~ Win2000是不支持的!!


program Project2;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows,
  System.SysUtils,
  System.Classes,
  System.Math,
  JwaWinCrypt;


Function GetFileSizeEx(hFile: THandle; Var lpFileSizeHigh :UInt64):Boolean; stdcall; external kernel32 name 'GetFileSizeEx';


Function GetFileHash4Md5(FileDirectory :PChar):String;
Const
  Buffer_Threshold = 1024 * 1024;
Label OnFail;
Var
  hFile      :THandle;
  hMapFile   :THandle;
  dwFileSize :UInt64;
  dwFileSizeH:DWORD;

  hProv      :HCRYPTPROV;
  hHash      :HCRYPTHASH;
  iIndex     :UInt64;
  dwBufSize  :DWORD;
  lpBuffer   :PByte;

  lpHash     :Array [0..MAXCHAR] Of Byte;
  dwHashLen  :DWORD;
  szHash     :Array [0..MAXCHAR] Of Char;
begin
  Writeln('文件:', FileDirectory);
  Result   := '';
  lpBuffer := Nil;
  hMapFile := INVALID_HANDLE_VALUE;
  hFile    := CreateFile(FileDirectory, GENERIC_READ, FILE_SHARE_READ, Nil,OPEN_EXISTING, 0, 0);
  if hFile = INVALID_HANDLE_VALUE then
  begin
    Writeln('CreateFile Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

  if Not GetFileSizeEx(hFile, dwFileSize) then
  begin
    Writeln('GetFileSizeEx Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;
  Writeln('大小:', dwFileSize, ' 字节');

  hMapFile := CreateFileMapping(hFile, Nil, PAGE_READONLY, 0, 0, Nil);
  if hMapFile = INVALID_HANDLE_VALUE then
  begin
    Writeln('CreateFileMapping Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

  if Not CryptAcquireContext(hProv, Nil, Nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT Or CRYPT_MACHINE_KEYSET) Then
  begin
    Writeln('CryptAcquireContext Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

  if Not CryptCreateHash(hProv, CALG_MD5,0, 0, hHash) Then
  begin
    Writeln('CryptCreateHash Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

  iIndex := 0;
  while iIndex < dwFileSize do
  begin
    dwBufSize := Min(dwFileSize - iIndex, Buffer_Threshold);
    lpBuffer  := MapViewOfFile(hMapFile, FILE_MAP_READ, Int64Rec(iIndex).Hi, Int64Rec(iIndex).Lo, dwBufSize);
    if lpBuffer = Nil then
    begin
      Writeln('MapViewOfFile Error, ErrorCode:', GetLastError);
      Goto OnFail;
    end;

    if Not CryptHashData(hHash, lpBuffer, dwBufSize, 0) then
    begin
      Writeln('CryptHashData Error, ErrorCode:', GetLastError);
      Goto OnFail;
    end;

    UnmapViewOfFile(lpBuffer);
    Inc(iIndex, Buffer_Threshold);
  end;

  dwBufSize := SizeOf(DWORD);
  dwHashLen := 0;
  if CryptGetHashParam(hHash, HP_HASHSIZE, @dwHashLen, dwBufSize, 0) then
  begin
    ZeroMemory(@lpHash, SizeOf(lpHash));
    if CryptGetHashParam(hHash, HP_HASHVAL, @lpHash, dwHashLen, 0) Then
    begin
      for dwFileSizeH := 0 to dwHashLen-1 do
      begin
        wsprintf(@szHash, '%s%02x', szHash, lpHash[dwFileSizeH]);
      end;
      Writeln('MD5:', String(szHash));
    end Else
    begin
      Writeln('Error getting hash value, ErrorCode:', GetLastError);
      Goto OnFail;
    end;  
  end Else
  begin
    Writeln('Error getting hash length value, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

OnFail:
  CryptDestroyHash(hHash);
  CryptReleaseContext(hProv, 0);
  UnmapViewOfFile(lpBuffer);
  CloseHandle(hFile);
  CloseHandle(hMapFile);
end;


begin
  GetFileHash4Md5('E:\ISO\cn_windows_server_2016_updated_feb_2018_x64_dvd_11636703.iso');
  Readln;
end.