Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / February 2008

Tip: Looking for answers? Try searching our database.

Getting HDD Serial of C drive.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Sin Jeong-hun - 04 Feb 2008 16:21 GMT
Below is the code in Managed C++. It was originally written in C, and
posted somewhere around the Internet (I forgot where I copied this
code), and I changed it into Managed C++. This code returnes the
serial string like "WD-WC1234567" of the hard disk where C drive is
on.

Now, I would like to change this code into C#, but there are so many
API's, structures and macroes. I've searched the Internet for
equivalent C# code but I couldn't find a working one. Is there any
existing C# equivalent code, or do I need to stick to this MC++ code?
Thank you.

                static String^ GetHddSerial()
                {
                    String^ test=System::String::Empty;
                    LPCWSTR damn=L"\\\\.\\c:";
                    HANDLE hPhysicalDriveIOCTL = CreateFile(damn, GENERIC_READ |
GENERIC_WRITE,
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
NULL);
                    if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
                    {
                        DWORD dwBytesReturned = 0;
                        //Get Physical Drive Information
                        VOLUME_DISK_EXTENTS vdExtents;
                        ZeroMemory(&vdExtents, sizeof(vdExtents));
                        if(!DeviceIoControl(hPhysicalDriveIOCTL,
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0,
                            &vdExtents, sizeof(vdExtents), &dwBytesReturned, NULL))
                        {
                            CloseHandle(hPhysicalDriveIOCTL);
                            throw gcnew System::ApplicationException("Error volumes that
span multiple disks are not supported");
                        }

                        //Get SMART version information
                        GETVERSIONINPARAMS gvopVersionParams;
                        ZeroMemory(&gvopVersionParams, sizeof(gvopVersionParams));
                        if(!DeviceIoControl(hPhysicalDriveIOCTL, SMART_GET_VERSION,
NULL, 0,
                            &gvopVersionParams, sizeof(gvopVersionParams),
&dwBytesReturned, NULL))
                        {
                            CloseHandle(hPhysicalDriveIOCTL);
                            throw gcnew System::ApplicationException("Error cannot get
SMART version information from device");
                        }

                        if(gvopVersionParams.bIDEDeviceMap > 0)
                        {
                            //Setup SMART request
                            SENDCMDINPARAMS InParams = {
                                IDENTIFY_BUFFER_SIZE, { 0, 1, 1, 0, 0,
((vdExtents.Extents[0].DiskNumber & 1) ? 0xB0 : 0xA0),
                                ((gvopVersionParams.bIDEDeviceMap >>
vdExtents.Extents[0].DiskNumber & 0x10) ? ATAPI_ID_CMD : ID_CMD) },
                                (BYTE)vdExtents.Extents[0].DiskNumber
                            };

                            DWORD dwBufSize = sizeof(SENDCMDOUTPARAMS) +
IDENTIFY_BUFFER_SIZE;
                            PSENDCMDOUTPARAMS pbtIDOutCmd = (PSENDCMDOUTPARAMS) new
BYTE[dwBufSize];
                            ZeroMemory(pbtIDOutCmd, dwBufSize);

                            //Get SMART information
                            if(DeviceIoControl(hPhysicalDriveIOCTL, SMART_RCV_DRIVE_DATA,
&InParams, sizeof(SENDCMDINPARAMS),
                                pbtIDOutCmd, dwBufSize, &dwBytesReturned, NULL))
                            {
                                //Little Endian To Big Endian
                                USHORT *pIDSector = (USHORT*)pbtIDOutCmd->bBuffer;
                                for(int nShort = 10; nShort < 21; nShort++)
                                    pIDSector[nShort] = (((pIDSector[nShort] & 0x00FF) << 8) +
((pIDSector[nShort] & 0xFF00) >> 8));

                                //Get Drive Serial Number
                                LPSTR lpszSerialNumber1 = new CHAR[21];
                                ZeroMemory(lpszSerialNumber1, 21);
                                RtlCopyMemory(lpszSerialNumber1, &pIDSector[10], 20);

                                //Remove those horrible spaces caused because of endianess
                                //and print out the serial
                                LPSTR lpszSerialNumber2 = lpszSerialNumber1;
                                while(*lpszSerialNumber2 == ' ') lpszSerialNumber2++;
                                test= gcnew System::String(lpszSerialNumber2);
                                delete lpszSerialNumber1;
                            }
                            delete pbtIDOutCmd;
                        }
                        else
                        {
                            CloseHandle(hPhysicalDriveIOCTL);
                            throw gcnew System::ApplicationException("Unknown error");
                        }
                        CloseHandle (hPhysicalDriveIOCTL);
                    }
                    return test;
                }
Ben Voigt [C++ MVP] - 04 Feb 2008 17:16 GMT
> Below is the code in Managed C++. It was originally written in C, and
> posted somewhere around the Internet (I forgot where I copied this
[quoted text clipped - 7 lines]
> existing C# equivalent code, or do I need to stick to this MC++ code?
> Thank you.

That's C++/CLI, not Managed Extensions for C++, and you are much better off
using that for Windows API calls than C#.  Not only can you use the C
headers intact, avoiding p/invoke declaration bugs, but it's faster as well.

> static String^ GetHddSerial()
> {
[quoted text clipped - 83 lines]
> return test;
> }
Peter Bromberg [C# MVP] - 04 Feb 2008 18:09 GMT
This article is quite old, but it looks like it has what you want (also
CPUId, MACaddress, etc.)
http://www.eggheadcafe.com/articles/20030511.asp
-- Peter
Site: http://www.eggheadcafe.com
UnBlog: http://petesbloggerama.blogspot.com
MetaFinder: http://www.blogmetafinder.com 

> Below is the code in Managed C++. It was originally written in C, and
> posted somewhere around the Internet (I forgot where I copied this
[quoted text clipped - 95 lines]
>                     return test;
>                 }

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.