Click here to Skip to main content
Click here to Skip to main content

Write a UDF CDR

By , 22 Jul 2003
 

Introduction

Some electronic devices need to use CDR as storage media, and you have to append several files each time before the space is used out. In this case, UDF is a good solution, since for each writing, only 7 logic blocks of overhead are used. (Multisession CDs use several minutes for each session's leadout)

How to use the demo

(You need WNASPI32.dll to run the demo, which could be downloaded from Ahead.)
  • Select the CDR drive you want to write to.
  • Insert a blank disc, "Format" it.
  • Browse to select files, and write to the disc. (Now you can view the files using DirectCD).
  • You can list the content of the CDR, and restore files to hard disk
  • Close Session, now any CD drive can read it..

How to use the source code

//Create a variable for your drive
SCSI2 m_drive;
//m_HA:HostAdpaterNumber,m_ID:SCSI ID,m_LUN:LogicUnitNumber
m_drive.SCSISelectDevice(m_HA,m_ID,m_LUN);
//For a blank CDR, you need to format it 
m_drive.FormatDisc("VOL1");
//Then you can write files onto it
m_drive.WriteFiles("Test1.bmp");
//Append more files here...
//
//After you have writen ALL the files, close the session
m_drive.CloseSession();
//Now it's readable by regular CDROM drive.

Some useful functions

SCSIRead()      //Read data from CDR
WritePacket()      //Write packets to CDR
ReadTrackInfo()      //Read track info, like next writable address
ReadDiskInfo()      //Read disc info, like capacity
TestUnitReady()      //See if the drive is ready
LoadUnload()      //Eject/Close the tray
SetWriteParameters()    //Set write mode
SCSISetSpeed()      //Set read/write speed
ListFiles()      //List files on the CDR
SaveFileAs()      //Save file on CDR to hard disk

If you want to know more inside stuff

Things you need to have:
  • SCSI command block structure (ANSI X3.131-1994)
  • SCSI multimedia commands-2 (ANSI NCITS 333-2000)
  • OSTA specs: ECMA-167, Universal Disk Format Specification, ECMA-119
Things you need to know:
  • SCSI2 block command structure
  • Use of ASPI
  • Concepts about CDR: track, session, logical blocks, PMA, ATIP, TOC, write modes...
  • UDF(Volume structure, file system)

More info at my website.

Revision History

  • Ver 1.01
    • More comments, some code clean up
    • New function: ListFiles()
    • New function: SaveFileAs()
  • Ver 1.02
    • Some changes on the demo application

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

spotofleopard
Engineer
United States United States
Member
Wheels I reinvented on various embedded systems
 
*License Plate Reader
*TCP/IP stack
*Web Server
*HTTP/FTP/SMTP client
*Ethernet/SCSI/USB drivers
*FAT32/UDF file system
*JPEG/MJPEG encoder

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalexplain note 4 in ATAPI code fixsussfkking25 May '04 - 13:13 
You ask about this note
 
4. Needs to double check the write address and re-allocation buffer in the
write files routines. Note: The sync cache after write fixs the problem.
The next write address is then properly read.
 
--------------------------------------------
I can't understand what this words mean...
Can I get the explanation about this?
I need your help ...
It'll be very nice if you can help me..
--------------------------------------------
Answer:
 
To issue a SYNC_CACHE command after ATAPI write is to force the data in the buffer out to disc and update the track information. The read track information will then return the proper information, specially, the next available write address. Thus:
 
in the early part of
 
bool SCSI2::WriteFiles (CString fileName) {
 
add the following statement:
SyncCache();
while( TestUnitReady() );

some time before the
 
ReadTrackInfo(0,&ti);
int lastLeadOut=toInt32(ti.track_start_addr)+toInt32(ti.track_size);
m_lba=toInt32(ti.next_writtable_addr);
 
With these arrangement, the statement at later would not fail.
 

BYTE* buffer=new BYTE[block_size*totalBlocks];

if(m_lba+totalBlocks+7>lastLeadOut){
AfxMessageBox("Disk Full!");
return false;
 
To ensure the file data is all out and not stuck in the buffer. add
 
SyncCache();
while( TestUnitReady() );
ReadDiskInfo(&di); // this one is not necessary
 

at close to end of the routine before
 
delete buffer;
delete list;
return result;

 
This arrangement also eliminate the "drive is stuck in the write " unless the buffer gets empty.
 

 

GeneralRe: explain note 4 in ATAPI code fixmemberfullluck27 May '04 - 1:20 
Thank you for reply ~
This is very helpful to me~!
But I have still some problem..
 
After Formatting the disc I can't get right VATICB addr..
 
I think there's some serious problem in my code..
 
bool SCSI2::SyncCache()
{
srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD;
srbExec.SRB_HaId = m_HA;
srbExec.SRB_Target = m_ID;
srbExec.SRB_Lun = m_LUN;
srbExec.SRB_Flags = SRB_DIR_OUT;
srbExec.SRB_SenseLen = SENSE_LEN;
srbExec.SRB_BufLen = 0;
srbExec.SRB_BufPointer = 0;
srbExec.SRB_CDBLen = 12;
srbExec.CDBByte [ 0 ] = SCSI_SYNC_CACHE;
srbExec.CDBByte [ 7 ] = 0;
srbExec.CDBByte [ 8 ] = 0;
 
pfnSendASPI32Command ( ( LPSRB ) &srbExec );
while ( srbExec.SRB_Status == SS_PENDING );
if(checkError(srbExec.SRB_Status)!="SUCCESS"&&!m_silence){
m_sense=*(scsi_sense *)srbExec.SenseArea;
AfxMessageBox(checkSense());
}
 
Is there any problem?

GeneralRe: explain note 4 in ATAPI code fixmemberfkking28 May '04 - 10:27 
1. srbExec.SRB_Flags = SRB_EVENT_NOTIFY;
2. your still need buffer for sense data
3. after sync cache, then
ReadTrackInfo(0,&ti);
 
sample for yor reference
 

memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD;
srbExec.SRB_HaId = m_HA;
srbExec.SRB_Flags = SRB_EVENT_NOTIFY;
srbExec.SRB_Target = m_ID;
srbExec.SRB_Lun = m_LUN;
srbExec.SRB_BufLen = 36;
srbExec.SRB_BufPointer = szBuffer;
srbExec.SRB_SenseLen = SENSE_LEN;
srbExec.SRB_CDBLen = 12;
srbExec.CDBByte [ 0 ] = 0x35;
srbExec.CDBByte [ 1 ] = 0; //Immediate is 1
srbExec.CDBByte [ 5 ] = 0; //logi addr 0
srbExec.CDBByte [ 8 ] = 0;

pfnSendASPI32Command ( ( LPSRB ) &srbExec );
while ( srbExec.SRB_Status == SS_PENDING );
if(checkError(srbExec.SRB_Status)!="SUCCESS"&&!m_silence){
m_sense=*(scsi_sense*)srbExec.SenseArea;
AfxMessageBox(checkSense());
return false;
}
 
memset(blk,0,block_size);
track_info ti;
 
ReadTrackInfo(0,&ti);
int lastLeadOut=toInt32(ti.track_start_addr)+toInt32(ti.track_size);
m_lba=toInt32(ti.next_writtable_addr);

int lastVATICB_Addr=m_lba-8;
QuestionWhat's mean this error code?memberholysky10019 May '04 - 19:20 
sense key: 0×5, asc=0×21, ascq=0×0

 
brown baek
AnswerRe: What's mean this error code?sussfkking25 May '04 - 13:15 
Invalid Command Op Code
GeneralDVD RAM FormatsussAnonymous12 May '04 - 5:48 
Will this work with a DVD RAM ? Can this format a dvd ram in udf ?
GeneralRe: DVD RAM Formatmembernico0416 Aug '04 - 4:24 
This code must be modified to run with DVD-RAM.
DVD-RAM works like a hard drive : No tracks, sessions... Only sectors (or blocks).
 

GeneralRe: DVD RAM FormatmemberKenThompson10 Mar '08 - 3:07 
I modified your code to format a DVD-RAM (in Vista) However, vista is unable to read the disc afterwards. (It says its blank)
 
Here are my questions:
 
First: When you write the udf header you start at a location other than 0, why is that?
Second: How many blocks does the header take up?
 
My work around was somewhat interesting. I've used vista to format the DVD, then I opened the volume and copied the first 4096 blocks into a file on my hard drive. When I want a blank DVD, I simply copy the bytes back on to the volume. Do you see a major issue with this approach?
 
Ken
GeneralCD writer is not detectingsussPrashant N12 Apr '04 - 20:39 
Hi,
This is Prashant from India. I have down load your sample application from codeproject.com. When I run this application, it is not detecting CD writer connected there to my system. On system I am using has WindowsXp OS, and Adaptec Drivers
1. aspi32.sys (ver. 4.71.2)
2. wowpost.exe (ver. 4.6(1021))
3. winaspi.dll (ver. 4.6(1021))
4. wnaspi32.dll (ver. 4.71.2)
 
Please let me know what shoud I do so using Adaptec driver this application will detect IDE CD Writer (IDE Sony CD writer.)
 
regards
Prashant
GeneralLast block informationmemberkiran_128 Apr '04 - 2:47 
Hi,
 
I am working on UDF file system decoder. I am blocked as of now and I cannot proceed further until I get to know how to get last block information. Please help me out!
 
Regards
Kiran

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 23 Jul 2003
Article Copyright 2002 by spotofleopard
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid