??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
此阶D主要是能熟l地使用某种语言。这q当于l武中的套\和架式这些表面的东西?br>W二阶段
此阶D能_N基于某U^台的接口Q例如我们现在常用的Win 32的API函数Q以及所对应语言的自w的库函数。到达这个阶D后Q也q当于可以q行真实散打对练了,可以真正地在实践中做些应用?br>W三阶段
此阶D能深入C解某个^台系l的底层Q已l具有了初的内功的能力Q也是“手中有剑Q心中无?#8221;?br>W四阶
此阶D能直接在^Cq行比较深层ơ的开发。基本上Q能辑ֈq个层次可以说是进入了高层ơ。这时进入了高内功的修点{比如能q行VxD或操作系l的内核的修攏V?br>q时已经不再有语a的束~,语言只是一U工P即要用自己不会的语aq行开发,也只是简单地熟悉一下,手到擒来,完全不像是第一阶段的时候学习语a的那U情c一般来_从第三阶D过渡到W四阶段是比较困隄。ؓ什么会隑֑Q这是因ؓ很多人的思想变不q来?br>W五阶
此阶D就已经不再局限于单的技术上的问题了Q而是能从全局上把握和设计一个比较大的系l体pȝ构,从内核到外层界面。可以说?#8220;手中无剑Q心中有?#8221;。到了这个阶D以后,能对市面上的M软gq行剖析Qƈ能按自己的要求进行设计,q是MS Wordq样的大型YӞ只要有充的旉Q也一定会设计出来?br>W六阶
此阶D也是最高的境界Q达?#8220;无招胜有?#8221;。这时候,M问题q_变成了一个思\的问题,不是用什么代码就能表C的。也是“手中无剑Q心中也无剑”?br>此时Q对于练功的人来_他已不用再去学什么少林拳Q只是在旁看一下少林拳的对战,p把此x来就用。这是真正的大师的h物。这ӞWin 32或Linux在你眼里是没有什么差别的?br>每一个阶D再向上发展旉要按一定的Ҏ。第一、第二个阶段通过自学可以完成,只要多用心去研究Q耐心地去学习?br>要想从第二个阶段q渡到第三个阶段Q就要有一个好的学习环境。例如有一个高手带领或公司里有一个好的练手环境。经q二、三q的U篏p辑ֈW三个阶Dc但是,有些人到辄三个阶段后,常常很难有境界上的H破了。他们这时会产生一U观念,认ؓ软g无非如此Q认己已无所不能。其实,q时如果遇到大的或难些的软gQ他们往往q是无从下手?br>现在我们国家大部分程序员都是在第二、三U之间。他们大多都是通过自学成才的,不过q样的程序员一般在软g公司也能独当一面,完成一些Y件的模块?br>但是Q也q有一
]]>
it讯交网
http://www.it315.org
q个|站是我最q才发现的,虽然内容不多Q但是提供的相关java工具挺齐全。还有就是里面提供了java教学视频录象的免费下载,好像一两周更换一Dc个得挺适合初学者的Q尤其是那个classpath的设|,讲的很透彻Q大家有I可以看一看?br>
java官方站点(英文)
http://java.sun.com
要想了解最新的java动态,下蝲最新的java相关Q比如j2se、j2ee、j2se的最新jdk版本来q里吧?br>
java中文?br>http://www.java-cn.com
q个可能大家都知道,不用说了Q他提供的java资源是最丰富的。注册论坛是免费的,q送积分,用积分可以下载Y件和电子书等Q如果积分用完了Q就需要自己发表一些文章来赚新的积分?br>
中文java|站
http://www.cn-java.com
跟上面站点类似的一个站Q宗旨就是:为java爱好者服务。值得一看!
锋网
http://www.ijsp.net/tech/book/index.jsp
l合性的java|站Q内?#8220;下蝲中心”?#8220;教程教学”{栏目?br>
java动力
http://eww.cn
|站的内容可以,但是最为出色的是它所q用的flash技术,我就不在q里多说了,大家ȝ看就知道了,一个字“?#8221;Q!Q?br>
vc斚w的:
vc知识?br>http://www.vckbase.com
q个|站׃用多说了Q学习vc必去之地。网站专门提供了免费的ftp下蝲Q好东东巨多Q?br>
vc之\
http://www.vcroad.com
l合软g开发网站,以vcZ?#8220;资源中心”有许多值得下蝲的东东?br>
visual c++/mfc开发指?br>http://www.vchelp.net
以讲qwindows开发ؓȝ站点Q提供了最新的源代码,开发工P开发资料,开发教E和对好的开发站点,开发工P图书做介l,同时Z事开发的朋友提供发布自己开发的软gQ代码和工具场所?
cl视?br>http://www.c-view.org/root/index.htm
最q发现的vc好站Q书c、Y件、代码下载一应具全!Q!
游戏开发:
风云工作?br>http://member.netease.com/~cloudwu/2000/index.html
标点游戏制作
http://makegame.myetang.com/
未来开发?br>http://www.fdev.net/
l合的:
中国软g|?br>http://www.csdn.net
中国最大的开发者网l,他之所以著名就是因Z的论坛,大家有空可以ȝ看,能下到很多不错的东东Q另外也是交学习的好地斏V?br>
电子书籍的:
http://www.itebook.net
最后公布一个巨好的Q狂多的电子书下?br>http://www.pdown.net
q有巨好?br>http://www.codestudy.net/default.asp
我会不断完善q个帖子Q要是斑竹允许,L?/span>
]]>
实际上,您可以把索引理解ZU特D的目录。微软的SQL SERVER提供了两U烦引:聚集索引Qclustered indexQ也U聚cȝ引、簇集烦引)和非聚集索引Qnonclustered indexQ也U非聚类索引、非集索引Q。下面,我们举例来说明一下聚集烦引和非聚集烦引的区别Q?br>
其实Q我们的汉语字典的正文本w就是一个聚集烦引。比如,我们要查“?#8221;字,׃很自然地d字典的前几页Q因?#8220;?#8221;的拼x“an”Q而按照拼x序汉字的字典是以英文字母“a”开头ƈ?#8220;z”l尾的,那么“?#8221;字就自然地排在字典的前部。如果您d了所有以“a”开头的部分仍然找不到这个字Q那么就说明您的字典中没有这个字Q同LQ如果查“?#8221;字,那您也会您的字典翻到最后部分,因ؓ“?#8221;的拼x“zhang”。也是_字典的正文部分本w就是一个目录,您不需要再L其他目录来找到您需要找的内宏V?br>
我们把这U正文内Ҏw就是一U按照一定规则排列的目录UCؓ“聚集索引”?br>
如果您认识某个字Q您可以快速地从自动中查到q个字。但您也可能会遇到您不认识的字,不知道它的发韻Iq时候,您就不能按照刚才的方法找到您要查的字Q而需要去Ҏ“偏旁部首”查到您要扄字,然后Ҏq个字后的页码直接翻到某|扑ֈ您要扄字。但您结?#8220;部首目录”?#8220;字表”而查到的字的排序q不是真正的正文的排序方法,比如您查“?#8221;字,我们可以看到在查部首之后的检字表?#8220;?#8221;的页码是672,字表?#8220;?#8221;的上面是“?#8221;字,但页码却?3,“?#8221;的下面是“?#8221;字,面?90c很昄Q这些字q不是真正的分别位于“?#8221;字的上下方,现在您看到的q箋?#8220;驰、张、徃”三字实际上就是他们在非聚集烦引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过q种方式来找到您所需要的字,但它需要两个过E,先找到目录中的结果,然后再翻到您所需要的늠?br>
我们把这U目录纯_Ҏ目录Q正文纯_Ҏ正文的排序方式称?#8220;非聚集烦?#8221;?br>
通过以上例子Q我们可以理解到什么是“聚集索引”?#8220;非聚集烦?#8221;?br>
q一步引申一下,我们可以很容易的理解Q每个表只能有一个聚集烦引,因ؓ目录只能按照一U方法进行排序?br>
Q二Q何时用聚集烦引或非聚集烦?br>
下面的表ȝ了何时用聚集烦引或非聚集烦引(很重要)?br>
动作描述
使用聚集索引
使用非聚集烦?br>
列经常被分组排序
?br>?br>
q回某范围内的数?br>?br>不应
一个或极少不同?br>不应
不应
数目的不同?br>?br>不应
大数目的不同?br>不应
?br>
频繁更新的列
不应
?br>
外键?br>?br>?br>
主键?br>?br>?br>
频繁修改索引?br>不应
?br>
事实上,我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如Q返回某范围内的数据一V比如您的某个表有一个时间列Q恰好您把聚合烦引徏立在了该列,q时您查?004q??日至2004q?0?日之间的全部数据Ӟq个速度将是很快的Q因为您的这本字典正文是按日期进行排序的Q聚cȝ引只需要找到要索的所有数据中的开头和l尾数据卛_Q而不像非聚集索引Q必d查到目录中查到每一Ҏ据对应的늠Q然后再Ҏ늠查到具体内容?br>
Q三Q结合实际,谈烦引用的误区
理论的目的是应用。虽然我们刚才列Z何时应用聚集烦引或非聚集烦引,但在实践中以上规则却很容易被忽视或不能根据实际情况进行综合分析。下面我们将Ҏ在实践中遇到的实际问题来谈一下烦引用的误区Q以便于大家掌握索引建立的方法?br>
1、主键就是聚集烦?br>
q种xW者认为是极端错误的,是对聚集索引的一U浪贏V虽然SQL SERVER默认是在主键上徏立聚集烦引的?br>
通常Q我们会在每个表中都建立一个ID列,以区分每条数据,q且q个ID列是自动增大的,步长一般ؓ1。我们的q个办公自动化的实例中的列Gid是如此。此Ӟ如果我们这个列设ؓ主键QSQL SERVER会将此列默认集烦引。这样做有好处,是可以让您的数据在数据库中按照IDq行物理排序Q但W者认样做意义不大?br>
显而易见,聚集索引的优势是很明昄Q而每个表中只能有一个聚集烦引的规则Q这使得聚集索引变得更加珍贵?br>
从我们前面谈到的聚集索引的定义我们可以看出,使用聚集索引的最大好处就是能够根据查询要求,q速羃查询范_避免全表扫描。在实际应用中,因ؓIDh自动生成的,我们q不知道每条记录的IDP所以我们很隑֜实践中用IDhq行查询。这׃让ID可个主键作集烦引成ZU资源浪贏V其ơ,让每个ID号都不同的字D作集烦引也不符?#8220;大数目的不同值情况下不应建立聚合索引”规则Q当Ӟq种情况只是针对用户l常修改记录内容Q特别是索引的时候会负作用,但对于查询速度q没有媄响?br>
在办公自动化pȝ中,无论是系l首|C的需要用L收的文g、会议还是用戯行文件查询等M情况下进行数据查询都M开字段的是“日期”q有用户本n?#8220;用户?#8221;?br>
通常Q办公自动化的首会昄每个用户未{收的文件或会议。虽然我们的where语句可以仅仅限制当前用户未{收的情况,但如果您的系l已建立了很长时_q且数据量很大,那么Q每ơ每个用h开首页的时候都q行一ơ全表扫描,q样做意义是不大的,l大多数的用?个月前的文g都已l浏览过了,q样做只能徒增数据库的开销而已。事实上Q我们完全可以让用户打开pȝ首页Ӟ数据库仅仅查询这个用戯3个月来未阅览的文Ӟ通过“日期”q个字段来限制表扫描Q提高查询速度。如果您的办公自动化pȝ已经建立?q_那么您的首页昄速度理论上将是原来速度8倍,甚至更快?br>
在这里之所以提?#8220;理论?#8221;三字Q是因ؓ如果您的聚集索引q是盲目地徏在IDq个主键上时Q您的查询速度是没有这么高的,即您在“日期”q个字段上徏立的索引Q非聚合索引Q。下面我们就来看一下在1000万条数据量的情况下各U查询的速度表现Q?个月内的数据?5万条Q:
Q?Q仅在主键上建立聚集索引Qƈ且不划分旉D:
Select gid,fariqi,neibuyonghu,title from tgongwen
用时Q?28470毫秒Q即Q?28U)
Q?Q在主键上徏立聚集烦引,在fariq上徏立非聚集索引Q?br>
select gid,fariqi,neibuyonghu,title from Tgongwen
where fariqi> dateadd(day,-90,getdate())
用时Q?3763毫秒Q?4U)
Q?Q将聚合索引建立在日期列QfariqiQ上Q?br>
select gid,fariqi,neibuyonghu,title from Tgongwen
where fariqi> dateadd(day,-90,getdate())
用时Q?423毫秒Q?U)
虽然每条语句提取出来的都?5万条数据Q各U情늚差异却是巨大的,特别是将聚集索引建立在日期列时的差异。事实上Q如果您的数据库真的?000万容量的话,把主键徏立在ID列上Q就像以上的W??U情况,在网上的表现就是超ӞҎ无法显C。这也是我摒弃ID列作集烦引的一个最重要的因素?br>
得出以上速度的方法是Q在各个select语句前加Qdeclare @d datetime
set @d=getdate()
q在select语句后加Q?br>
select [语句执行p旉(毫秒)]=datediff(ms,@d,getdate())
2、只要徏立烦引就能显著提高查询速度
事实上,我们可以发现上面的例子中Q第2?条语句完全相同,且徏立烦引的字段也相同;不同的仅是前者在fariqi字段上徏立的是非聚合索引Q后者在此字D上建立的是聚合索引Q但查询速度却有着天壤之别。所以,q是在M字段上简单地建立索引p提高查询速度?br>
从徏表的语句中,我们可以看到q个有着1000万数据的表中fariqi字段?003个不同记录。在此字D上建立聚合索引是再合适不q了。在现实中,我们每天都会发几个文Ӟq几个文件的发文日期q同,q完全符合徏立聚集烦引要求的Q?#8220;既不能绝大多数都相同Q又不能只有极少数相?#8221;的规则。由此看来,我们建立“适当”的聚合烦引对于我们提高查询速度是非帔R要的?br>
3、把所有需要提高查询速度的字D都加进聚集索引Q以提高查询速度
上面已经谈到Q在q行数据查询旉M开字段的是“日期”q有用户本n?#8220;用户?#8221;。既然这两个字段都是如此的重要,我们可以把他们合qv来,建立一个复合烦引(compound indexQ?br>
很多为只要把M字段加进聚集索引Q就能提高查询速度Q也有h感到qhQ如果把复合的聚集烦引字D分开查询Q那么查询速度会减慢吗Q带着q个问题Q我们来看一下以下的查询速度Q结果集都是25万条数据Q:Q日期列fariqi首先排在复合聚集索引的v始列Q用户名neibuyonghu排在后列Q?br>
Q?Qselect gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>'2004-5-5'
查询速度Q?513毫秒
Q?Qselect gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>'2004-5-5' and neibuyonghu='办公?
查询速度Q?516毫秒
Q?Qselect gid,fariqi,neibuyonghu,title from Tgongwen where neibuyonghu='办公?
查询速度Q?0280毫秒
从以上试验中Q我们可以看到如果仅用聚集烦引的起始列作为查询条件和同时用到复合聚集索引的全部列的查询速度是几乎一LQ甚x?/span>
]]>
int WINAPI MessageBoxA(HWND,LPCSTR,LPSTR,UINT);
而WINAPI实际上就是__stdcall.
大多数API都采用__stdcall调用规范,q是因ؓ几乎所有的语言都支持__stdcall调用.相比之下,__cdecl只有在C语言中才能用.但是__cdecl调用有一个特?是能够实现可变参数的函数调?比如printf,q用__stdcall调用是不可能?
__fastcallq种调用规范比较见,但是在Borland C++ Builder中比较多的采用了q种调用方式.
如果有共享代码的需?比如写DLL,推荐的方法是用__stdcall调用,因ؓq样适用范围最q?如果是C++语言写的代码供Delphiq样的语a调用必d明ؓ__stdcall,因ؓPascal不支持cdecl调用(或许Delphi的最新版本能够支持也说不?q个我不太清?.在其他一些地?比如写COMlg,几乎都用的是stdcall调用.在VC或Delphi或C++Builder里面都可以从目讄中更攚w认的函数调用规范,当然你也可以在函数声明的时候加入__stdcall,__cdecl,__fastcall关键字来明确的指C本函数用哪U调用规?
__declspec一般都是用来声明DLL中的导出函数.q个关键字也有一些其他的用法,不过非常|见.
]]>
#define _ALV_TREE_H
#define Max(a,b) (((a)>(b))?(a):(b))
#include <iostream>
template<class T>
class AVLTree
{
struct _TreeNode;
typedef struct _TreeNode TreeNode;
struct _TreeNode
{
T data;
int height;
TreeNode* left;
TreeNode* right;
};
private:
TreeNode *root;
public:
AVLTree()
{
this->root=NULL;
}
~AVLTree()
{
this->MakeEmpty(this->root);
}
int GeiHeight()
{
return this->GetHeightUtil(this->root);
}
void Insert(T data)
{
this->root=this->InsertUtil(this->root,data);
}
void Delete(T data)
{
this->root=this->DeleteUtil(this->root,data);
}
void Print()
{
/*if(root!=NULL)
{
std::cout<<"The root node is: "<<root->data<<std::endl;
}*/
for(int level=0;;level++)
{
if(this->PrintUtil(this->root,level)==0)
{
break;
}
std::cout<<std::endl;
}
}
private:
TreeNode *InsertUtil(TreeNode *_root,T data)
{
if(_root==NULL)
{
_root=new TreeNode();
_root->data=data;
_root->left=0;
_root->right=0;
_root->height=0;
}
if(data>_root->data)
{
_root->right=this->InsertUtil(_root->right,data);
if(GetHeightUtil(_root->right)-GetHeightUtil(_root->left)==2)
{
if(data>_root->right->data)
{
_root=this->SingleRotateWithRight(_root);
}
else
{
_root=this->DoubleRotateWithRight(_root);
}
}
}
else if(data<_root->data)
{
_root->left=this->InsertUtil(_root->left,data);
if(GetHeightUtil(_root->left)-GetHeightUtil(_root->right)==2)
{
if(data<_root->left->data)
{
_root=this->SingleRotateWithLeft(_root);
}
else
{
_root=this->DoubleRotateWithLeft(_root);
}
}
}
_root->height=Max(GetHeightUtil(_root->left),GetHeightUtil(_root->right))+1;
return _root;
}
TreeNode *DeleteUtil(TreeNode *_root,T data)
{
if(_root==NULL)
{
return _root;
}
else if(_root->data==data
&&_root->left==NULL
&&_root->right==NULL)
{
delete _root;
return NULL;
}
else if(_root->data==data
&&_root->left!=NULL
&&_root->right==NULL)
{
TreeNode* tmpNode=_root->left;
delete _root;
tmpNode->height=this->RecalculateHeight(tmpNode);
return tmpNode;
}
else if(_root->data==data
&&_root->left==NULL
&&_root->right!=NULL)
{
TreeNode *tmpNode=_root->right;
delete _root;
tmpNode->height=this->RecalculateHeight(tmpNode);
return tmpNode;
}
else
{
if(data==_root->data)
{
TreeNode *tmpNode,*parentNode;
tmpNode=_root->right->right;
parentNode=_root->right;
if(tmpNode!=NULL)
{
while(tmpNode->right!=NULL)
{
parentNode->height-=1;
parentNode=tmpNode;
tmpNode=tmpNode->right;
}
parentNode->right=NULL;
_root->data=tmpNode->data;
delete tmpNode;
}
else
{
_root=parentNode;
}
_root->height=this->RecalculateHeight(_root);
//TreeNode *tmpNode=this->FindMax(_root->right);
//_root->data=tmpNode->data;
if(GetHeightUtil(_root->left)-GetHeightUtil(_root->right)==2)
{
if(_root->left->left!=NULL)
{
_root=this->SingleRotateWithLeft(_root);
}
else if(_root->left->right!=NULL)
{
_root=this->DoubleRotateWithLeft(_root);
}
}
}
else
if(data>_root->data)
{
_root->right=this->DeleteUtil(_root->right,data);
_root->height=this->RecalculateHeight(_root);
if(GetHeightUtil(_root->left)-GetHeightUtil(_root->right)==2)
{
if(_root->left->left!=NULL)
{
_root=this->SingleRotateWithLeft(_root);
}
else if(_root->left->right!=NULL)
{
_root=this->DoubleRotateWithLeft(_root);
}
}
}
else
{
_root->left=this->DeleteUtil(_root->left,data);
_root->height=this->RecalculateHeight(_root);
if(GetHeightUtil(_root->right)-GetHeightUtil(_root->left)==2)
{
if(_root->right->right!=NULL)
{
_root=this->SingleRotateWithRight(_root);
}
else if(_root->right->left!=NULL)
{
_root=this->DoubleRotateWithRight(_root);
}
}
}
}
//_root->height=this->RecalculateHeight(_root);
return _root;
}
void MakeEmpty(TreeNode *_root)
{
if(_root==NULL)
{
return;
}
else
{
MakeEmpty(_root->left);
MakeEmpty(_root->right);
delete _root;
}
}
int GetHeightUtil(TreeNode *_root)
{
/*if(_root==NULL|| (_root->left==NULL && _root->right==NULL))
{
return 0;
}
else
{
return 1+GetHeightUtil(_root->left)+GetHeightUtil(_root->right);
}*/
if(_root==NULL)
{
return -1;
}
else
{
return _root->height;
}
}
int PrintUtil(TreeNode *node, int level)
{
if(node==NULL||level<0)
{
return 0;
}
else
{
if(level==0)
{
std::cout<<node->data<<" ";
return 1;
}
return PrintUtil(node->left,level-1)+PrintUtil(node->right,level-1);
}
}
TreeNode *SingleRotateWithLeft(TreeNode *node)
{
TreeNode *tmpNode=node->left;
node->left=tmpNode->right;
tmpNode->right=node;
node->height=Max(GetHeightUtil(node->left),GetHeightUtil(node->right))+1;
tmpNode->height=Max(GetHeightUtil(tmpNode->left),GetHeightUtil(tmpNode->right))+1;
return tmpNode;
}
TreeNode*SingleRotateWithRight(TreeNode *node)
{
TreeNode *tmpNode=node->right;
node->right=tmpNode->left;
tmpNode->left=node;
node->height=Max(GetHeightUtil(node->left),GetHeightUtil(node->right))+1;
tmpNode->height=Max(GetHeightUtil(tmpNode->left),GetHeightUtil(tmpNode->right))+1;
return tmpNode;
}
TreeNode* DoubleRotateWithLeft(TreeNode *node)
{
node->left=this->SingleRotateWithRight(node->left);
return this->SingleRotateWithLeft(node);
}
TreeNode* DoubleRotateWithRight(TreeNode *node)
{
node->right=this->SingleRotateWithLeft(node->right);
return this->SingleRotateWithRight(node);
}
TreeNode* FindMax(TreeNode *node)
{
//T maxData;
while(node!=NULL&&node->right!=NULL)
{
node=node->right;
}
//maxData=node->data;
return node;
}
int RecalculateHeight(TreeNode *node)
{
if(node==NULL)
{
return -1;
}
else
{
node->height=Max(RecalculateHeight(node->left),RecalculateHeight(node->right))+1;
return node->height;
}
}
};
#endif
1。选择配置属?>链接?>调试->生成调试信息 改ؓ ?
2。选择 配置属?>C/C++ ->常规->调试信息格式 改ؓ 用于“~辑ql?#8221;的程序数据库(/ZI)
3。选择 配置属?>C/C++ ->优化->优化 改ؓ 自定?/strong>
重新~译Q运?/strong>
int main()
{
SECURITY_ATTRIBUTES secStru;
secStru.bInheritHandle=0;
secStru.lpSecurityDescriptor=0;
secStru.nLength=0;
HANDLE hDevice=CreateFile("\\\\.\\PhysicalDrive0",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(hDevice==INVALID_HANDLE_VALUE)
{
return -1;
}
//DWORD outBuff[1000];
GET_LENGTH_INFORMATION infoStruct;
memset(&infoStruct,0,sizeof(infoStruct));
DWORD bytesReturned;
if(DeviceIoControl(hDevice,IOCTL_DISK_GET_LENGTH_INFO,NULL,0,&infoStruct,sizeof(infoStruct),&bytesReturned,NULL)==0)
{
cout<<"Failed to get disk information."<<endl;
DWORD error;
error=GetLastError();
HRESULT hRe=HRESULT_FROM_WIN32(error);
char errorData[10];
sprintf(errorData,"%x",hRe);
cout<<"Error code:"<</*hRe*/errorData<<endl;
CloseHandle(hDevice);
return -1;
}
DISK_GEOMETRY_EX geoStruct;
memset(&geoStruct,0,sizeof(geoStruct));
if(DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_GEOMETRY_EX ,NULL,0,&geoStruct,sizeof(geoStruct),&bytesReturned,NULL)==0)
{
cout<<"Failed to get disk information."<<endl;
DWORD error;
error=GetLastError();
HRESULT hRe=HRESULT_FROM_WIN32(error);
char errorData[10];
sprintf(errorData,"%x",hRe);
cout<<"Error code:"<</*hRe*/errorData<<endl;
CloseHandle(hDevice);
return -1;
}
cout<<"The disk's size is:"<<infoStruct.Length.QuadPart/1024/1024/1024<<" G Bytes."<<endl;
cout<<"The disk's cylinder number:"<<geoStruct.Geometry.Cylinders.QuadPart<<endl;
cout<<"The disk's media type:"<<geoStruct.Geometry.MediaType<<endl;
cout<<"Number of tracks per cylinder:"<<geoStruct.Geometry.TracksPerCylinder<<endl;
cout<<"Number of sectors per track:"<<geoStruct.Geometry.SectorsPerTrack<<endl;
cout<<"Number of bytes per sector:"<<geoStruct.Geometry.BytesPerSector<<endl;
PDISK_PARTITION_INFO partitionInfo=DiskGeometryGetPartition(&geoStruct);
DRIVE_LAYOUT_INFORMATION_EX layOutInfo[20];
memset(&layOutInfo,0,sizeof(DRIVE_LAYOUT_INFORMATION_EX)*20);
//layOutInfo.PartitionEntry=*(new PARTITION_INFORMATION_EX[10]);
if(DeviceIoControl(hDevice,IOCTL_DISK_GET_DRIVE_LAYOUT_EX,NULL,0,&layOutInfo,sizeof(DRIVE_LAYOUT_INFORMATION_EX)*20,&bytesReturned,NULL)==0)
{
cout<<"Failed to get disk information."<<endl;
DWORD error;
error=GetLastError();
HRESULT hRe=HRESULT_FROM_WIN32(error);
char errorData[10];
sprintf(errorData,"%x",hRe);
cout<<"Error code:"<</*hRe*/errorData<<endl;
CloseHandle(hDevice);
return -1;
}
int partitionCount=layOutInfo[0].PartitionCount;
cout<<"Number of partitions:"<<layOutInfo[0].PartitionCount<<endl;
cout<<"Partitions' information:"<<endl;
for(int i=0;i<partitionCount;i++)
{
//PDISK_PARTITION_INFO pParInfo=partitionInfo+i*sizeof(DISK_PARTITION_INFO);
if(layOutInfo[i].PartitionEntry[0].PartitionNumber!=0)
{
cout<<"Partition "<<layOutInfo[i].PartitionEntry[0].PartitionNumber<<", partition size is "<<layOutInfo[i].PartitionEntry[0].PartitionLength.QuadPart/1024/1024/1024<<" G Bytes, partition style is "<<layOutInfo[i].PartitionEntry[0].PartitionStyle<<endl;
}
}
//cout<<"The type of partition:"<<((partitionInfo.PartitionStyle==PARTITION_STYLE_MBR) ?"MBR":((partitionInfo.PartitionStyle==PARTITION_STYLE_GPT )?"GPT":((partitionInfo.PartitionStyle==PARTITION_STYLE_RAW)?"RAW":"")))<<endl;
CloseHandle(hDevice);
return 0;
}