-
June 6th, 2002, 08:19 PM
#1
How do I change a floppy's serial number
I am working on an application where I need to change the volume id (serial number) of a floppy disk. I have not found a way to do this through the API yet. Can anyone help?
-
June 7th, 2002, 01:36 PM
#2
The Volume ID and the Sericl number of any disk are to different aninals. YOu can not change theSerial number. It is hardcoded in the disk.
The SetVolumeLabel API can be used to change the Volume label
'
Public Declare Function SetVolumeLabel Lib "kernel32" _
Alias "SetVolumeLabelA" _
(ByVal lpRootPathName As String, _
ByVal lpVolumeName As String) As Long
'
'
Public Function Label_Disk(ByVal Drive As String, Optional VolLabel As String)
' Input looks like "C:\","Label"
If Right(Drive, 1) <> "\" Then Drive = Drive & "\"
If VolLabel = "" Then
Label_Disk = SetVolumeLabel(Drive, vbNullChar)
Else
Label_Disk = SetVolumeLabel(Drive, VolLabel)
End If
End Function
-
June 7th, 2002, 06:29 PM
#3
You are correct that the volume label and serial number are two different items, but I know that it is possible to change the serial number of a floppy, or even a hard disk, because I have found several utilities that do this.
The problem is that I have to do it from within the application i'm working on.
Since it is possible, hopefully someone out there knows how to do it...
-
June 8th, 2002, 03:55 AM
#4
Yeah.. i agree.. im still looking for the way to change floopy serial no.
everytime i format the diskette, the serial no. will change
-
June 8th, 2002, 04:13 AM
#5
Since it changes when you format the disk, one (cheesy) way to do it for a floppy would be to grab all the data on the disk and store it in a temp file, format the disk, then put the data back.
-
June 8th, 2002, 06:05 AM
#6
Unfortunately just copying the data from the disk does not change the serial number.
I can use GetVolumeInformation to read the serial number, but I need to change it.
I even have a sample of QBasic code that can do this, but it does not translate well to VB (or at least I don't know how to do that).
If QBasic could do this, shouldn't there be a way in VB?
-
June 8th, 2002, 07:09 AM
#7
i found tat Delphi can do it easily too......
here the code..
function SetSerial(DiskNum : Byte; var I : TInfoBuffer) : word; assembler;
asm
mov ah, 69h
mov al, 01h
mov bl, DiskNum
push ds
lds dx, I
int 21h
pop ds
jc @bad
xor ax, ax
@bad:
end;
-
June 8th, 2002, 09:18 AM
#8
Ron Stone. Post the Qbasic code./ Maybe some one can figure it out.
-
June 8th, 2002, 09:37 AM
#9
I even have a sample of QBasic code that can do this, but it does not translate well to VB (or at least I don't know how to do that).
If QBasic could do this, shouldn't there be a way in VB?
I suspect it was written in Assembly language form -- though inserted in QBasic program. I recall, using Data statement in QBasic (which was lost in VB3 to VB6) you can actually write/insert pseudo-assembly code and run it on QBasic allowing it to access DOS system's level.
If you have this code, please post it here and let's see. If it is in pure QBasic form, I might be able to help because I spent more than 3 years in that language. But if it is in pseudo-Assembly, sorry. That is one thing I didn't learn in QBasic.
Aio
Marketing our skills - please participate in the survey and share your insights
-
-
June 8th, 2002, 03:46 PM
#10
Here is the QBasic code I found to change the serial number.
'===========================================================================
' Subject: CHANGE DISK SERIAL NUMBER Date: 09/93 (00:00)
' Author: Andy Thomas Code: QB, PDS
' Keys: CHANGE,DISK,SERIAL,NUMBER Packet: DISK.ABC
'===========================================================================
DEFINT A-Z
' Purpose: To change the serial number on any DOS disk.
' WARNING THE FOLLOWING PROGRAM USES DIRECT DISK WRITES!
' by Andy Thomas 9/93
' Author not responsible for misuse or errors of any kind.
' Use of this program could, but should not, damage your disk
' or render data unusable.
'$INCLUDE: 'QB.BI'
' QB must be started with the /L switch!
DIM inreg AS RegTypeX, outreg AS RegTypeX
CLS
TYPE DiskPacketType
Sector AS LONG ' DWORD - starting sector number
CountWrite AS INTEGER ' WORD - Number of sectors affected
TransAddres AS STRING * 4 ' DWORD - Location of data transfer
' Address
END TYPE
' Note: Sector is a LONG while TransAddres is a string
' because we know Sector is going to be zero for this program.
' In other uses Sector would need to be made a string to avoid
' QuickBasic OVERFLOW errors.
DIM DiskPacket AS DiskPacketType ' Disk Write Packet
DIM DataStorage AS STRING * 512 ' string to read/write sector
PRINT "Place disk in drive." ' get drive to change
PRINT "Enter drive letter:";
DO
Drive$ = UCASE$(INKEY$)
LOOP UNTIL Drive$ <> ""
PRINT Drive$
PRINT
DriveNumb = ASC(Drive$) - 65 ' drive number: A:=0, B:=1....
inreg.cx = &HFFFF ' Read/Write Absolute Sector
inreg.ax = DriveNumb ' Drive id
DiskPacket.Sector = 0 ' start at sector 0
DiskPacket.CountWrite = 1 ' load one sector
'DWORD -- Seg:Off of DataStorage
DiskPacket.TransAddres = CHR$(VARPTR(DataStorage) AND &HFF) +_
CHR$(((VARPTR(DataStorage) AND &HFF00) \ 256) AND &HFF) +_
CHR$((VARSEG(DataStorage) AND &HFF)) +_
CHR$(((VARSEG(DataStorage) AND &HFF00) \ 256) AND &HFF)
inreg.ds = VARSEG(DiskPacket) ' DS:BX = Disk write packet
inreg.bx = VARPTR(DiskPacket)
CALL INTERRUPTX(&H25, inreg, outreg) ' read disk sector
' Get serial number from boot sector
FOR I = &H2B TO &H28 STEP -1
OldSerial$ = OldSerial$ + HEX$(ASC(MID$(DataStorage, I, 1)))
IF LEN(OldSerial$) = 4 THEN OldSerial$ = OldSerial$ + "-"
NEXT I
PRINT " Old serial number:"; OldSerial$
LOCATE 5, 1
PRINT "Enter new serial Number:"
' get user input for new serial number
' making sure only a valid serial number is entered
Ptr = 0
DashAdj = 0
DO
DO
A$ = UCASE$(INKEY$)
LOOP UNTIL (INSTR("0123456789ABCDEF" + CHR$(8), A$) > 0) AND_
A$ <> ""
IF A$ = CHR$(8) THEN ' backspace for corrections
IF Ptr > 0 THEN
Ptr = Ptr - 1
NewSerial$ = LEFT$(NewSerial$, Ptr)
ELSE
NewSerial$ = ""
END IF
ELSE
Ptr = Ptr + 1
NewSerial$ = NewSerial$ + A$
END IF
LOCATE 5, 25
PRINT " "
LOCATE 5, 25
PRINT LEFT$(NewSerial$, 4)
IF Ptr > 4 THEN
LOCATE 5, 29
PRINT "-" + MID$(NewSerial$, 5, 8)
END IF
LOOP UNTIL Ptr = 8
Ptr = 0
' Convert NewSerial$ into numerical ASCII codes
' and save within DataStorage
FOR I = &H2B TO &H28 STEP -1
Sbyte = 0
FOR J = 1 TO 2
A$ = MID$(NewSerial$, J + Ptr, 1)
IF ASC(A$) > 64 AND ASC(A$) < 71 THEN Adj = 55 ELSE Adj= 48
Sbyte = (Sbyte * 16) + (ASC(A$) - Adj)
NEXT J
DEF SEG = VARSEG(DataStorage)
POKE VARPTR(DataStorage) + I - 1, Sbyte
Ptr = Ptr + 2
NEXT I
' Check to make sure new serial number was placed in
' correct location (this is a redundant check for safety)
FOR I = &H2B TO &H28 STEP -1
ChkSerial$ = ChkSerial$ + HEX$(ASC(MID$(DataStorage, I, 1)))
IF LEN(ChkSerial$) = 4 THEN ChkSerial$ = ChkSerial$ + "-"
NEXT I
' confirm change
PRINT
PRINT " disk:"; Drive$
PRINT " from serial number:"; OldSerial$
PRINT "to new serial number:"; ChkSerial$
PRINT "Confirm change: (Y/N)"
DO
A$ = UCASE$(INKEY$)
LOOP UNTIL A$ = "Y" OR A$ = "N"
IF A$ = "Y" THEN ' make the change
DiskPacket.TransAddres = CHR$(VARPTR(DataStorage) AND &HFF) +_
CHR$(((VARPTR(DataStorage) AND &HFF00) \ 256) AND &HFF) +_
CHR$((VARSEG(DataStorage) AND &HFF)) +_
CHR$(((VARSEG(DataStorage) AND &HFF00) \ 256) AND &HFF)
inreg.ds = VARSEG(DiskPacket) ' DS:BX = Disk write packet
inreg.bx = VARPTR(DiskPacket)
CALL INTERRUPTX(&H26, inreg, outreg) ' write disk sector
ELSE
PRINT "Change Aborted."
END IF
END
' Methodology: The disk serial number is stored as a Double
' Word in the boot sector (sector zero) of every disk at
' location 27h. This program reads sector zero into a string,
' changes the dword value at offset 27h and writes the changed
' data back to sector zero. While this program should work, and
' has been tested on both hard drives and floppy disks, I
' suggest it only be used on floppy drives, as a error
' occurring while writing to sector zero on the hard drive
' could be disastrous.
-
June 8th, 2002, 10:37 PM
#11
Awwkkkkk
Awk -- Interrupt handling.
Though I understand the code very well, I am at a loss. These functions are lost in VB (Var Seg, Poke, VarPtr). I think Interrupt handling was also lost.
Will check first the (probable) API equivalent. Hope someone here can point the way.
The program was actually wriiten in QuickBasic -- Not QBasic. They are slightly different. QBasic could not handle this statement:
QBasic treat it as comment while QuickBasic treat it as compiler directive.
Last edited by aio; June 8th, 2002 at 10:40 PM.
Marketing our skills - please participate in the survey and share your insights
-
-
June 8th, 2002, 11:33 PM
#12
Is it not possible tp read and write to sector zero like the above QuickBasic code?
If I am reading it correctly, that code reads sector zero, chanves the values for the serial number, then writes the sector again.
-
June 9th, 2002, 04:05 PM
#13
Using direct Reads and Writes I am sure is forbidden under Windows, at least it willl be available only the priviledged few like Format.
Qbasic runs under DOS which could care less what Program A does since it is the only program running. Under Windows you can have many programs running at the same time and getting down to that level of modifications could impact many programs and screw up Windows quite badly.
Don't forget also that you have AntiVirus programs to contend with. Most of them get upset also if you try to screw around with System reserved components.
'
You might want to review why you need to do this.
-
June 9th, 2002, 08:25 PM
#14
As I stated earlier, I have already found utilities that can modify the floppy's serial number. These programs are doing it under windows without interfering with the operating system or anti-virus software, so maybe they are not using the direct read-write shown in the QuickBasic code above, but there obviously is a way to do it.
What I need is help with a solution.
-
June 10th, 2002, 06:04 PM
#15
I don't think you can use in-line assembler in VB6 - you *might* be able to use it in vb.net. Anyway, to answer your question (theoretically) , the only way I can think of is to create a C/C++ dll using in-line assembler code, exposing the functions as required, then call that dll from your vbcode.
(MSDN)
The __asm keyword invokes the inline assembler and can appear wherever a C or C++ statement is legal. It cannot appear by itself. It must be followed by an assembly instruction, a group of instructions enclosed in braces, or, at the very least, an empty pair of braces. The term “__asm block” here refers to any instruction or group of instructions, whether or not in braces.
The following code fragment is a simple __asm block enclosed in braces:
__asm
{
mov al, 2
mov dx, 0xD007
out al, dx
}
Alternatively, you can put __asm in front of each assembly instruction:
__asm mov al, 2
__asm mov dx, 0xD007
__asm out al, dx
As to actually writing the serial no - that's a little beyond me.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|