當前位置:首頁 » 比特幣問答 » iovc轉換btc

iovc轉換btc

發布時間: 2021-09-18 07:02:18

① 如何用vc作串口和網路通信

你要找虛擬串口?
虛擬串口就是當本地並沒有對應的串口硬體設備,而為應用層提供串口設備一樣的系統調用介面,以兼容原本使用本地串口的應用軟體的「虛」設備。本文作者給出了一種在Windows平台上實現虛擬串口的方法,由此實現的「串口」具有真實串口完全相同的系統調用介面。

在很多應用中需要用到虛擬串口,如在Modem卡出現之前,已經有了接在計算機串口上的外部Modem,而且各種拔號程序也是通過串口與外部Modem通信的。為了讓已有的拔號程序不做修改,像使用外部Modem一樣使用內置卡,就需要內置卡的驅動程序虛擬一個串口設備。又如當前工業界使用的一些串口伺服器,往往有8個或16個甚至更多的串口,以連接多個串口設備,再通過一個網卡直接連入乙太網。與它在同一網路上的計算機就通過乙太網與串口伺服器上掛接的串口設備通信。為了讓計算機中原來使用本地串口的軟體兼容,就需要在計算機上提供虛擬串口驅動。

虛擬串口的設計關鍵在於,該「串口」實現後必須具有與真實串口完全相同的系統調用介面。要做到這點,從已有的串口設備驅動程序上做修改是最佳捷徑。下文就介紹以Windows NT上的串口驅動程序為基礎,開發可運行於Windows NT、Windows 2000、Windows XP的各個版本虛擬串口驅動程序。

串口驅動中使用的幾個鏈表

由於串口是雙工設備,在一個讀請求發出來還沒有完成之前,同時可以發出寫請求,加上在驅動程序層所有I/O請求都要求非同步完成,即前一個請求尚沒有完成,下一個相同的請求可能又來了。為此,串口驅動程序需要使用多個雙向鏈表數據結構來處理各種IRP(I/O Request Packet,I/O請求包)。當收到一個IRP,先判斷是否可立即完成,可以馬上處理並返回,如果不允許則將IRP插在相應鏈表尾,在適當的時候如設備有空閑時處理,這時往往會產生一個硬體中斷,激發DPC(Deferred Procere Call,暫緩過程調用)過程,由DPC處理函數逐個從鏈表頭取出IRP並試著完成它。串口驅動中有以下幾個鏈表和DPC(在serial.h中有定義):

ReadQueue 和 CompleteReadDpc

用於保存Read IRP的鏈表和用於調度的DPC,與DPC對應的處理函數是SerialCompleteRead,它在read.c文件中,該函數的主要任務就是從ReadQueue中提取下一個IRP,並試著完成它。

WriteQueue 和 CompleteWriteDpc

用於保存Write IRP的鏈表和對應的DPC,與DPC對應的函數是SeriaCompleteWrite,它的實現在write.c中,該函數負責從WriteQueue中提取IRP,並試著完成它。

MaskQueue 和 CommWaitDpc

這一對鏈表用於處理Windows串口驅動的一個特性:事件驅動機制。它允許應用程序預設一個事件標志,而後等待與標志對應事件發生。DPC所調用的函數是SerialCompleteWait,它實現在Waitmask.c文件中,該函數也是試著從MaskQueue中提取IRP並完成它。

PurgeQueue

該鏈表與前面幾個稍有不同,它沒有與之相對應的DPC機制,而是在每次收到Purge請求時從PurgeQueue中逐個提取IRP並試著完成,因某種原因不能完成時則插入鏈表。相應的函數是purge.c文件中的SerialStartPurge。

以上機制是串口驅動程序的重要實現方法,在虛擬串口驅動中需要保留,但不同的是,硬體串口驅動中是ISR(中斷服務程序)根據收、發或MODEM中斷來激發相應的DPC,而在虛擬串口驅動中將因實際情況不同會有不同的激發機制。

DriverEntry的實現

DriverEntry是驅動程序的入口函數,相當於應用程序C語言中的main函數,開發一個虛擬串口驅動首先要修改的就是它。它的函數實體在initunlo.c文件中。只是在虛擬串口驅動中由於不與具體的硬體打交道,就不存在硬體資源分析、硬體初始化、判斷其工作狀態等處理,只需要為虛擬串建立設備對象、符號鏈接和初始化數據結構。一個典型函數實現大體如下:

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

{

/*填寫DriverObject->MajorFunction[]數組*/

/*建立設備對象*/

/*初始化SERIAL_DEVCIE_EXETENSION數據結構*/

Status = IoCreateDevice(DriverObject, sizeof(SERIAL_DEVICE_EXTENSION), &uniNameString, FILE_DEVICE_SERIAL_PORT, 0,TRUE,&deviceObject);

//初始化所有鏈表

InitializeListHead(&extension->ReadQueue);

InitializeListHead(…);

…;

//初始化所有DPC

KeInitializeDpc(&extension->CompleteReadDpc,SerailCompleteRead,extension);

KeInitializeDpc(…);

/*建立符號鏈接*/

SerialSetupExternalNaming(extension);

return Status;

}

SerialRead和SerialCompleteRead的實現

函數SerailRead和SerialCompleteRead決定了對Read IRP的響應策略,它們都存於read.c中。以串口伺服器要用的虛擬串口為例,當串口伺服器收到來自外部數據時將通過網路發至計算機,計算機則產生相應的網路中斷並進行協議數據處理。網路接收線程緩存新收到的數據並激活CompleteReadDpc,從而SerialCompleteReadIrp得到調用,它再調用CompleteReadIrp對每個IRP進行處理。它們的實現大體如下:

NTSTATUS SerialRead(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)

{

/*此處略去變數聲明和初始化*/

/*提取IRP中相關的數據*/

stack = IoGetCurrentIrpStackLocation(Irp);

ReadLen = stack->Parameters.Read.Length;

/*先看本地緩沖有數據否?有的話先讀取*/

if(Extension->InCounter > 0 )

{ //注意這里要加鎖,以防數據訪問沖突

KeAcquireSpinLock(&Extension->

ReadBufferLock,&lIrql);

FirstRead = (ReadLen>Extension->

InCounter)? Extension->InCounter: ReadLen;

RtlCopyMemory(Irp->AssociatedIrp.

SystemBuffer,Extension->pInBuffer,FirstRead);

Extension->InCounter -= FirstRead;

ReadLen -= FirstRead;

KeReleaseSpinLock(&Extension->

ReadBufferLock,lIrql);//釋放鎖

}

/*是否已讀到足夠數據?是的話則完成該IRP*/

if( 0 == ReadLen)

{

status=STATUS_SUCCESS;

Irp->IoStatus.Status = status;

Irp->IoStatus.Information = FirstRead;

IoCompleteRequest(Irp,0);

return status;

}

/*沒有則將IRP插入隊列中,通過網路向串口伺服器發出讀數據請求*/

IoMarkIrpPending(Irp);

InsertWaitList(Extension->ReadQueue,Irp);

status = TdiSendAsync(Extension->ComChannel,pAckPacket,PacketLen(pAckPacket),(PVOID)ReadAckComplete,Irp);

/*返回PENDING,表示該IRP尚沒有完成*/

return STATUS_PENDING;

}

Void CompleteReadIrp(IN PSERIAL_DEVICE_EXTENSION extension,IN PIRP Irp,IN PUCHAR pInData,IN ULONG Length )

{

/*此處略去變數聲明和初始化*/

/*讀取新數據*/

ReadLen = (ReadLen > Length)? Length : ReadLen;

if(ReadLen != 0)

{

RtlCopyMemory(pReadAsync->

pReadBuffer,pInData,ReadLen);

pReadAsync->pReadBuffer += ReadLen;

pReadAsync->ReadAlready += ReadLen;

extension->PerfStats.ReceivedCount +=

ReadLen;

}

else

{

/*因為串口伺服器端只有在已經有了相應的數據或超過時間(此時,Length=0)才會發來應答並激活本DPC過程,所以此時已經超時,為了便於結束本IRP,這里有意改變TotalNeedRead,造成接收完畢的假象*/

pReadAsync->TotalNeedRead =

pReadAsync->ReadAlready;

}

if(pReadAsync->TotalNeedRead == pReadAsync->ReadAlready)

{

/*該IRP是否已經接收完畢,是的話則結束該

IRP*/

EndReadIrp(Irp);

/*從ReadQueue中取下一個IRP*/

}

/*本IRP沒有完成也沒有超時,則繼續等待本DPC下次被激活,注意此時要判斷IRP是否被要求取消*/

}

SerialWrite和SerailCompleteWrite的實現

SerialWrite和SerailCompleteWrite決定了Write IRP的實現。在SerialWrite中調用了網路發送函數TdiSendAsync,當該發送完成後將激活CompleteWriteDpc,調度SerialCompleteWrite函數,而它主要就是取出當前的WriteIRP,設置已經發送的數據數量,調用CompleteWriteIrp做該IRP的進一步處理。它們大體如下:

NTSTATUS SerialWrite(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)

{

/*此處略去變數聲明和初始化*/

/*從IRP中提取有關數據*/

stack=IoGetCurrentIrpStackLocation(Irp);

SendLen = stack->Parameters.Write.Length;

/*為網路發送和非同步操作分配緩沖,在CompleteWrite中全部數據發送完後釋放*/

pWriteAsync = ExAllocatePool(NonPagedPool,

SendLen+PACKET_HEADER_LEN+sizeof(WRITE_ASYNC));

if(pWriteAsync == NULL)

{

//錯誤處理

}

//保存非同步數據



//設置網路發送數據包

BuildDataPacket(pPacket,WRITE,(USHORT)SendLen,pWriteAsync->pWriteBuffer);

/*先將IRP暫時阻塞並插入隊列,在CompleteWrite中完成*/

IoMarkIrpPending(Irp);

InsertWaitList(extension->WriteQueue, Irp);

/*將寫請求和相關數據通過網路發向串口伺服器,由它負責將數據傳到具體串口設備*/

status = TdiSendAsync(Extension->ComChannel,pPacket,PacketLen(pPacket),(PVOID)CompleteWriteIrp,Irp);

//統計數據累加

Extension->PerfStats.TransmittedCount += SendLen;

return STATUS_PENDING;

}

NTSTATUS CompleteWriteIrp(IN PDEVICE_OBJECT deviceobject,IN PIRP pIrp,IN PVOID context)

{

/*此處略去變數聲明和初始化*/

SendLen=pWriteAsync->TotalNeedWrite - pWriteAsync->WroteAlready;

if(SendLen == 0)//全部數據發送完畢

{

EndWaitWriteIrp(pWriteIrp,STATUS_SUCCESS,

pWriteAsync->WroteAlready,pWriteAsync);

//從WriteQueue中取下一個IRP;

}

else //發送剩餘數據

{

if(pWriteIrp->Cancel)

{

//IRP被要求取消,完成WriteIrp

EndWaitWriteIrp(pWriteIrp,STATUS_CANCELLED,

pWriteAsync->WroteAlready,pWriteAsync);

return STATUS_CANCELED;

}

else

{

//再次設置網路數據包並發送

BuildDataPacket(…);

status = TdiSendAsync(…);

//統計數據累加

Extension->PerfStats.TransmittedCount +=

SendLen;

return STATUS_MORE_PROCESSING_REQUIRED;

}

}

}

其他幾個介面函數的實現

除Read/Write外,SerialUnload、SerialCreateOpen、 SerialClose、SerialCleanup、SerailFlush等調用介面是硬體相關性比較弱的介面函數,基本不要修改,直接刪除原來操作硬體的部分即可。復雜一點就是SerialIoControl,該介面函數包含有大量設置、讀取串口硬體狀態的處理,可建立一個本地數據結構隨時保存虛擬串口的當前硬體狀態。同時為了保證串口伺服器端的真實串口狀態和上層軟體要求的一致,需要將所有設置請求通過網路發送到伺服器端,由它負責改變真實硬體的狀態。

② VC++ 6.0 goto 語句

把int c;改成char c;即可,因為輸入的e, E等都是字元,

若c是int類型,cin >> c; 輸入字元型,cin會忽略而不讀取,輸入的值就一直存在緩沖區,goto start後,由於緩沖區不為空,cin優先從緩沖區讀取,結果就死循環了。

③ Gate.io永續合約資金劃轉最小可轉入多少BTC

最小可轉入0.0001BTC

④ 3D MAX的文件如何轉為GTA VC 的DFF文件 要詳細的過程

kam』tools 插件 ┣ 關於kamtools for 3dmax插件使用說明(MOD製作過程教程)━━━━━━━━━━━━━━━━━━

Q:如何運行DFF IO 插件?

A:打開3dmax後>>>MaxScript菜單>>>Run Script>>>找到你3dmax安裝目錄里SCRIPT文件包內GTAtools裡面的相關插件打開就可以運行了插件了。

Q:請問插件里有很多腳本他們的具體功能是什麼呢?

A:GTA_DFF_IO (導入DFF或輸出DFF必備
COL iO(汽車碰撞文件生成,地圖碰撞文件生成)
Kam_envelope_tools編緝人物NPC骨骼的插件

Q:請問通過本插件製作汽車過程是什麼?

A:汽車MOD是由DFF和TXD兩個文件DFF文件是模型文件,TXD是貼圖文件。DFF是通過GTA_DFF_IO將max里的模型和層次關系

⑴首先在3dmax里建造汽車模型,汽車模型是由模型實體和虛點組成的。並且通過鏈接層次來識別車子的某部位。可以通過dff io導入一個GTA里的車子。再用open schematic view鍵,此鍵在工具欄上(就是察看層次鏈接的)例:
下面簡單說一下層次結構以sandking這輛車子為例吧。模型有一個好模型和一個壞模型組成,壞模型就是車子損壞時的樣子。
最上層是sandking,他的下層有chassis_mmy((車體的)該虛點下麵包含四個門的好壞mmy),wheel_lf_mmy,wheel_rf_mmy,wheel_rb_mmy....(輪子的)ped_frontseat(這是前坐的虛點,坐人的地方後坐就是backseat),extra(此虛點可有可無,通過這個可以做刷出模型的不同掛件。想要刷出更多不同的東西。如:後備箱放個箱子,或是什麼的。命名為extra1。。。。。N就會刷出不同的掛件了),stop(該虛點可有可無,這是剎車車變亮)的。door_XX_mmy這是門的,它在chassis層次下面.它含有door_XX_dam好門,door_XX_ok壞門有四個門當然有的車是兩門的。大家了解了後自己親自導入一個車子看看就清楚了。

上面是簡單說一下車子的層次關系的。建議大家導入一個車子察看就明白了。

⑵將車子在max里貼圖,uvw調整貼圖坐標,如果是己有的模型這步就省了。貼圖使用圖片格式:bmp,tga,png要使用這三種格式的。也就是說把模型在max里貼圖要用bmp,tga,png這三種格式的。要是用jpg貼圖不行的哦。因為txd文件不識別這種格式。

⑶下面是如果通過dff io插件導出DFF文件到GTA裡面,用GTA_DFF_IO 插件,本貼有下載,全選模型和虛點(CTRL+A)注意:如果不全選會不能輸出,Export dff>>>再SA collision Base下面的select COL3/COLL選擇一個與你做的車子相仿的碰撞模型(隨便選個車子的dff文件就行了>>>打開>>>>最後Export dff就全部完成了。恭喜你成功了

Q:如果製作GTA里的貼圖文件TXD?

A:使用本貼工具txd workshop工具>>文件>>新建圖像>>32bit>>>工具欄上點「輸入」圖片就是你在MAX里用到的貼圖文件。注意:文件名一定要是max里用到的文件名哦>>>雙擊己輸入的圖片彈出屬性>>>>按下compressed按鈕並保存TXD文件>>>>成功。

總結要點:1.使用GTA_DFF_IO導入一個車子的DFF文件,再用open schematic view鍵,(此鍵在工具欄上)是察看層次鏈接的。可套用GTA里原來車子的層次鏈接。建議逐個替換(如自己做好一個車身或車門然後替換原來的車身和車門,現在就可以將原來的車身刪除了。這樣做不易出錯。) 也可以先將原來的模型「冷結」,再做自己新模型,一定要搞正確層次鏈接哦。不然進游戲會出錯!!
用3dmax製作模型再用進行貼圖,再用修改器的urwamp調整uvw貼圖坐標。貼圖使用格式為:bmp,tga,png切記,不然其它格式的圖片文件txd不認!!!

當模型做好,貼圖貼好,鏈接層次正確,這些完畢後就可以輸出了。(一定要檢查好,不然會出錯!!)

以上完畢後就可輸出DFF文件。最後製作TXD貼圖文件:注意在txd里新建的貼圖文件文件名,一定要是3dmax里使用的貼圖哦。
作者:購買快樂 2009-10-9 20:17 回復此發言

⑤ VC++ MFC如何獲取CPU ID及硬碟的序列號

// 「獲得Intel CPU ID」按鈕消息處理函數
void CIntelCPUIDDlg::OnBtnCPUID()
{
unsigned long s1,s2;
unsigned char vendor_id[]="------------";//CPU提供商ID
CString str1,str2,str3;
// 以下為獲得CPU ID的匯編語言指令
_asm // 得到CPU提供商信息
{
xor eax,eax // 將eax清0
cpuid // 獲取CPUID的指令
mov dword ptr vendor_id,ebx
mov dword ptr vendor_id[+4],edx
mov dword ptr vendor_id[+8],ecx
}
str1.Format("%s",vendor_id);

_asm // 得到CPU ID的高32位
{
mov eax,01h
xor edx,edx
cpuid
mov s2,eax
}
str2.Format("%08X-",s2);

_asm // 得到CPU ID的低64位
{
mov eax,03h
xor ecx,ecx
xor edx,edx
cpuid
mov s1,edx
mov s2,ecx
}
str3.Format("%08X-%08X\n",s1,s2);

str2=str2+str3;
m_editVendor.SetWindowText(str1);
m_editCPUID.SetWindowText(str2);
}

// GetHDSerial.cpp: implementation of the CGetHDSerial class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GetHDSerial.h"

char m_buffer[256];
WORD m_serial[256];
DWORD m_OldInterruptAddress;
DWORDLONG m_IDTR;

// 等待硬碟空閑
static unsigned int WaitHardDiskIdle()
{
BYTE byTemp;

Waiting:
_asm
{
mov dx, 0x1f7
in al, dx
cmp al, 0x80
jb Endwaiting
jmp Waiting
}
Endwaiting:
_asm
{
mov byTemp, al
}
return byTemp;
}

//中斷服務程序
void _declspec( naked )InterruptProcess(void)
{
int byTemp;
int i;
WORD temp;
//保存寄存器值
_asm
{
push eax
push ebx
push ecx
push edx
push esi
}

WaitHardDiskIdle();//等待硬碟空閑狀態
_asm
{
mov dx, 0x1f6
mov al, 0xa0
out dx, al
}
byTemp = WaitHardDiskIdle(); //若直接在Ring3級執行等待命令,會進入死循環
if ((byTemp&0x50)!=0x50)
{
_asm // 恢復中斷現場並退出中斷服務程序
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}

_asm
{
mov dx, 0x1f6 //命令埠1f6,選擇驅動器0
mov al, 0xa0
out dx, al
inc dx
mov al, 0xec
out dx, al //發送讀驅動器參數命令
}
byTemp = WaitHardDiskIdle();
if ((byTemp&0x58)!=0x58)
{
_asm // 恢復中斷現場並退出中斷服務程序
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
//讀取硬碟控制器的全部信息
for (i=0;i<256;i++)
{
_asm
{
mov dx, 0x1f0
in ax, dx
mov temp, ax
}
m_serial[i] = temp;
}
_asm
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGetHDSerial::CGetHDSerial()
{

}

CGetHDSerial::~CGetHDSerial()
{

}
// 讀取硬碟序列號函數
char* CGetHDSerial::GetHDSerial()
{
m_buffer[0]='\n';
// 得到當前操作系統版本
OSVERSIONINFO OSVersionInfo;
OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx( &OSVersionInfo);
if (OSVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
{
// Windows 9x/ME下讀取硬碟序列號
WORD m_wWin9xHDSerial[256];
Win9xReadHDSerial(m_wWin9xHDSerial);
strcpy (m_buffer, WORDToChar (m_wWin9xHDSerial, 10, 19));
}
else
{
// Windows NT/2000/XP下讀取硬碟序列號
DWORD m_wWinNTHDSerial[256];
// 判斷是否有SCSI硬碟
if ( ! WinNTReadIDEHDSerial(m_wWinNTHDSerial))
WinNTReadSCSIHDSerial(m_wWinNTHDSerial);
strcpy (m_buffer, DWORDToChar (m_wWinNTHDSerial, 10, 19));
}
return m_buffer;
}

// Windows9X/ME系統下讀取硬碟序列號
void _stdcall CGetHDSerial::Win9xReadHDSerial(WORD * buffer)
{
int i;
for(i=0;i<256;i++)
buffer[i]=0;
_asm
{
push eax
//獲取修改的中斷的中斷描述符(中斷門)地址
sidt m_IDTR
mov eax,dword ptr [m_IDTR+02h]
add eax,3*08h+04h
cli
//保存原先的中斷入口地址
push ecx
mov ecx,dword ptr [eax]
mov cx,word ptr [eax-04h]
mov dword ptr m_OldInterruptAddress,ecx
pop ecx
//設置修改的中斷入口地址為新的中斷處理程序入口地址
push ebx
lea ebx,InterruptProcess
mov word ptr [eax-04h],bx
shr ebx,10h
mov word ptr [eax+02h],bx
pop ebx
//執行中斷,轉到Ring 0(類似CIH病毒原理)
int 3h
//恢復原先的中斷入口地址
push ecx
mov ecx,dword ptr m_OldInterruptAddress
mov word ptr [eax-04h],cx
shr ecx,10h
mov word ptr [eax+02h],cx
pop ecx
sti
pop eax
}
for(i=0;i<256;i++)
buffer[i]=m_serial[i];
}

// Windows 9x/ME系統下,將字類型(WORD)的硬碟信息轉換為字元類型(char)
char * CGetHDSerial::WORDToChar (WORD diskdata [256], int firstIndex, int lastIndex)
{
static char string [1024];
int index = 0;
int position = 0;

// 按照高位元組在前,低位元組在後的順序將字數組diskdata 中內容存入到字元串string中
for (index = firstIndex; index <= lastIndex; index++)
{
// 存入字中的高位元組
string [position] = (char) (diskdata [index] / 256);
position++;
// 存入字中的低位元組
string [position] = (char) (diskdata [index] % 256);
position++;
}
// 添加字元串結束標志
string [position] = '\0';

// 刪除字元串中空格
for (index = position - 1; index > 0 && ' ' == string [index]; index--)
string [index] = '\0';

return string;
}

// Windows NT/2000/XP系統下,將雙字類型(DWORD)的硬碟信息轉換為字元類型(char)
char* CGetHDSerial::DWORDToChar (DWORD diskdata [256], int firstIndex, int lastIndex)
{
static char string [1024];
int index = 0;
int position = 0;

// 按照高位元組在前,低位元組在後的順序將雙字中的低字存入到字元串string中
for (index = firstIndex; index <= lastIndex; index++)
{
// 存入低字中的高位元組
string [position] = (char) (diskdata [index] / 256);
position++;
// 存入低字中的低位元組
string [position] = (char) (diskdata [index] % 256);
position++;
}
// 添加字元串結束標志
string [position] = '\0';

// 刪除字元串中空格
for (index = position - 1; index > 0 && ' ' == string [index]; index--)
string [index] = '\0';

return string;
}

// Windows NT/2000/XP下讀取IDE硬碟序列號
BOOL CGetHDSerial::WinNTReadIDEHDSerial(DWORD * buffer)
{
BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
BOOL bFlag = FALSE;
int drive = 0;
char driveName [256];
HANDLE hPhysicalDriveIOCTL = 0;

sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
// Windows NT/2000/XP下創建文件需要管理員許可權
hPhysicalDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);

if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
GETVERSIONOUTPARAMS VersionParams;
DWORD cbBytesReturned = 0;

// 得到驅動器的IO控制器版本
memset ((void*) &VersionParams, 0, sizeof(VersionParams));
if(DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_VERSION,
NULL, 0, &VersionParams,
sizeof(VersionParams),
&cbBytesReturned, NULL) )
{
if (VersionParams.bIDEDeviceMap > 0)
{
BYTE bIDCmd = 0; // IDE或者ATAPI識別命令
SENDCMDINPARAMS scip;

// 如果驅動器是光碟機,採用命令IDE_ATAPI_IDENTIFY, command,
// 否則採用命令IDE_ATA_IDENTIFY讀取驅動器信息
bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10)?
IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

memset (&scip, 0, sizeof(scip));
memset (IdOutCmd, 0, sizeof(IdOutCmd));
// 獲取驅動器信息
if (WinNTGetIDEHDInfo (hPhysicalDriveIOCTL,
&scip,
(PSENDCMDOUTPARAMS)&IdOutCmd,
(BYTE) bIDCmd,
(BYTE) drive,
&cbBytesReturned))
{
int m = 0;
USHORT *pIdSector = (USHORT *)
((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;

for (m = 0; m < 256; m++)
buffer[m] = pIdSector [m];
bFlag = TRUE; // 讀取硬碟信息成功
}
}
}
CloseHandle (hPhysicalDriveIOCTL); // 關閉句柄
}
return bFlag;
}

// WindowsNT/2000/XP系統下讀取SCSI硬碟序列號
BOOL CGetHDSerial::WinNTReadSCSIHDSerial (DWORD * buffer)
{
buffer[0]='\n';
int controller = 0;
HANDLE hScsiDriveIOCTL = 0;
char driveName [256];
sprintf (driveName, "\\\\.\\Scsi%d:", controller);
// Windows NT/2000/XP下任何許可權都可以進行
hScsiDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);

if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
{
int drive = 0;
DWORD mmy;
for (drive = 0; drive < 2; drive++)
{
char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;
SENDCMDINPARAMS *pin =
(SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
// 准備參數
memset (buffer, 0, sizeof (buffer));
p -> HeaderLength = sizeof (SRB_IO_CONTROL);
p -> Timeout = 10000;
p -> Length = SENDIDLENGTH;
p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
strncpy ((char *) p -> Signature, "SCSIDISK", 8);
pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
pin -> bDriveNumber = drive;
// 得到SCSI硬碟信息
if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,
buffer,
sizeof (SRB_IO_CONTROL) +
sizeof (SENDCMDINPARAMS) - 1,
buffer,
sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
&mmy, NULL))
{
SENDCMDOUTPARAMS *pOut =
(SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);
if (pId -> sModelNumber [0])
{
int n = 0;
USHORT *pIdSector = (USHORT *) pId;

for (n = 0; n < 256; n++)
buffer[n] =pIdSector [n];
return TRUE; // 讀取成功
}
}
}
CloseHandle (hScsiDriveIOCTL); // 關閉句柄
}
return FALSE; // 讀取失敗
}

// Windows NT/2000/XP下讀取IDE設備信息
BOOL CGetHDSerial::WinNTGetIDEHDInfo (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
PDWORD lpcbBytesReturned)
{
// 為讀取設備信息准備參數
pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
pSCIP -> irDriveRegs.bFeaturesReg = 0;
pSCIP -> irDriveRegs.bSectorCountReg = 1;
pSCIP -> irDriveRegs.bSectorNumberReg = 1;
pSCIP -> irDriveRegs.bCylLowReg = 0;
pSCIP -> irDriveRegs.bCylHighReg = 0;

// 計算驅動器位置
pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);

// 設置讀取命令
pSCIP -> irDriveRegs.bCommandReg = bIDCmd;
pSCIP -> bDriveNumber = bDriveNum;
pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;

// 讀取驅動器信息
return ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_DRIVE_INFO,
(LPVOID) pSCIP,
sizeof(SENDCMDINPARAMS) - 1,
(LPVOID) pSCOP,
sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
lpcbBytesReturned, NULL) );
}

⑥ VC 右移運算符的一個簡單的問題 麻煩指教

首先你要注意,你是用int賦值給char,會斷位。
iOfst>>0x08得到int的1是沒問題的,0x160右移,60會丟掉,1被移動到最右邊,左邊補0
ucCmd[1]=iOfst; //這個得到60也是對的,char只保存後8位的60,前面的被丟掉了。

⑦ Gateio杠桿 ETF 產品BTC3L 做多幣種,與 BTC3S 做空幣種交易時存在對應關系嗎

不存在的,之所以有做多做空的叫法,是因為兩者的漲跌幅度與標的幣種的對應關系不同。比如調倉後 BTC 漲跌幅為 1% ,在不考慮觸發不定時調倉的情況下, BTC3L 的凈值漲跌幅為3% , BTC3S 的凈值漲跌幅為 -3% 。所以, BTC3L 被稱為 BTC 做多, BTC3S 被稱為 BTC 做空。實際交易時,可以將兩者理解為兩個完全不同的現貨幣種,盈利方式與現貨市場其他幣種相同。

⑧ gate.io上比特幣如何轉換成人民幣

gate上有一個法幣交易區。

點進去,選擇btc交易,然後找到要賣與的人。按提示綁定銀行卡或者其他支付方式。等到收到對方的轉賬,然後確認收款就行了。

⑨ Win10系統在安裝某IO資料庫時,需安裝VC++2008等軟體庫,在安裝過程中提示:Error 1935

用別的系統比如win7/win8.1試一下,這軟體不一定對win10能提供良好支持,或者試一下搜索 3DM游戲運行庫合集安裝包 或者 游戲環境程序集合傻瓜安裝包 ,裝一下看看。

熱點內容
零幣礦機算力怎麼算 發布:2025-07-22 15:47:47 瀏覽:42
usdt可查嗎 發布:2025-07-22 15:38:19 瀏覽:338
USDT網路騙局 發布:2025-07-22 15:37:29 瀏覽:99
幣圈沒有隻漲不跌的 發布:2025-07-22 15:13:10 瀏覽:672
幣圈的m和b還有K各是什麼單位 發布:2025-07-22 15:12:06 瀏覽:11
doge貨幣發行量 發布:2025-07-22 15:09:42 瀏覽:523
300比特幣價格 發布:2025-07-22 15:05:37 瀏覽:749
比特幣礦場如何偷竊客戶算力 發布:2025-07-22 15:01:00 瀏覽:536
蓬萊離婚去政務中心嗎 發布:2025-07-22 14:43:02 瀏覽:165
以太坊平台使用價格 發布:2025-07-22 14:38:22 瀏覽:450