Hey everybody!
I am writing a program that will read and write the ID3 tag of an Mp3 music file.
The reading part I got some help with (found it on the net and worked it to my advantage =)
I am still trying to figure out what the part of concerning SECURITY_ATTRIBUTES means but that's not primary concern
//-- This is just sample from my program.... the explaining of the problem comes at end of code!
class newID3 // one thing, away from main problem, could I have used struct instead of class, and what's the difference?
{
public:
char title[31];
char artist[31];
char album[31];
char year[5];
char comments[31];
char genre[31];
};
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE handle; //handle the mp3 file
SECURITY_ATTRIBUTES security_attributes; //need it to open a file
//fill in the security struct
security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
security_attributes.lpSecurityDescriptor = NULL;
security_attributes.bInheritHandle = FALSE;
// Mp3File is a file in AnsiString format, not sure if this line is correct
// GENERIC_READ&GENERIC_WRITE for both reading and writing
// FILE_SHARE_READ&FILE_SHARE_WRITE not sure about this part what it exactly does
handle = CreateFile(Mp3File.c_str(),GENERIC_READ&GENERIC_WRITE, FILE_SHARE_READ&FILE_SHARE_WRITE, &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(!handle)
Abort(); // Error handling if file not loaded
if(SetFilePointer(handle, -128, NULL, FILE_END) == 0xFFFFFFFF) // pointing to a point in file 'handle'
CloseHandle(handle); // Error handling if not pointed to -128bytes from end
class newID3 tag;
// all txtID... are TEdit components and copies Text's to class newID3
// Maybe I made an error here, if so I can't see it at this moment
memcpy((void*)tag.title,(void*)(txtIDTitle->Text).c_str(),(size_t)30);
memcpy((void*)tag.artist,(void*)(txtIDArtist->Text).c_str(),(size_t)30);
memcpy((void*)tag.album,(void*)(txtIDAlbum->Text).c_str(),(size_t)30);
memcpy((void*)tag.year,(void*)(txtIDYear->Text).c_str(),(size_t)4);
memcpy((void*)tag.comments,(void*)(txtIDComment->Text).c_str(),(size_t)30);
// This is a TComboBox component
memcpy((void*)tag.genre,(void*)cmbGenre->Text.c_str(),(size_t)(strlen(cmbGenre->Text.c_str())));
//no stop signs exists in the id3 so we have to fill in those 'Got this part from another file'
tag.title[30] = '\0'; // not sure why it's needed
tag.artist[30] = '\0';
tag.album[30] = '\0';
tag.year[4] = '\0';
tag.comments[30] = '\0';
if(!WriteFile(handle,&tag,128,0,NULL)) // The problem is here.. It doesn't write to the file..
ShowMessage("Error while writing file!"
CloseHandle(handle);
}
//--- end of code
One part of the problem, I think, is how to get 'number of bytes written' - in WriteFile, se appendix 2
Could it be so that I should change some attributes in CreateFile - se appendix 1 - or use another function to open the file, and if so should I use another function to write to the file??
There is also something that just crossed my mind, how do I delete the last 128 bytes in the file before I write the new ID3 tag?
The programs main function is to read the last 128 bytes of an .mp3 file where the ID3 tag is stored
If you got any other solution how to write to the end of a file I will gratefully accept them all
Thanks Martin....!!
//--- Appendix ---//
// Appendix 1 //--- found in Borland help files
HANDLE CreateFile(
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);
// Appendix 2 //--- allso found in Borland help files
BOOL WriteFile(
HANDLE hFile, // handle to file to write to
LPCVOID lpBuffer, // pointer to data to write to file
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
);
Martin G Broman
mgb_svea@hotmail.com
DWS - Alpha Whitin Dead Wolf Society
I am writing a program that will read and write the ID3 tag of an Mp3 music file.
The reading part I got some help with (found it on the net and worked it to my advantage =)
I am still trying to figure out what the part of concerning SECURITY_ATTRIBUTES means but that's not primary concern
//-- This is just sample from my program.... the explaining of the problem comes at end of code!
class newID3 // one thing, away from main problem, could I have used struct instead of class, and what's the difference?
{
public:
char title[31];
char artist[31];
char album[31];
char year[5];
char comments[31];
char genre[31];
};
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE handle; //handle the mp3 file
SECURITY_ATTRIBUTES security_attributes; //need it to open a file
//fill in the security struct
security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
security_attributes.lpSecurityDescriptor = NULL;
security_attributes.bInheritHandle = FALSE;
// Mp3File is a file in AnsiString format, not sure if this line is correct
// GENERIC_READ&GENERIC_WRITE for both reading and writing
// FILE_SHARE_READ&FILE_SHARE_WRITE not sure about this part what it exactly does
handle = CreateFile(Mp3File.c_str(),GENERIC_READ&GENERIC_WRITE, FILE_SHARE_READ&FILE_SHARE_WRITE, &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(!handle)
Abort(); // Error handling if file not loaded
if(SetFilePointer(handle, -128, NULL, FILE_END) == 0xFFFFFFFF) // pointing to a point in file 'handle'
CloseHandle(handle); // Error handling if not pointed to -128bytes from end
class newID3 tag;
// all txtID... are TEdit components and copies Text's to class newID3
// Maybe I made an error here, if so I can't see it at this moment
memcpy((void*)tag.title,(void*)(txtIDTitle->Text).c_str(),(size_t)30);
memcpy((void*)tag.artist,(void*)(txtIDArtist->Text).c_str(),(size_t)30);
memcpy((void*)tag.album,(void*)(txtIDAlbum->Text).c_str(),(size_t)30);
memcpy((void*)tag.year,(void*)(txtIDYear->Text).c_str(),(size_t)4);
memcpy((void*)tag.comments,(void*)(txtIDComment->Text).c_str(),(size_t)30);
// This is a TComboBox component
memcpy((void*)tag.genre,(void*)cmbGenre->Text.c_str(),(size_t)(strlen(cmbGenre->Text.c_str())));
//no stop signs exists in the id3 so we have to fill in those 'Got this part from another file'
tag.title[30] = '\0'; // not sure why it's needed
tag.artist[30] = '\0';
tag.album[30] = '\0';
tag.year[4] = '\0';
tag.comments[30] = '\0';
if(!WriteFile(handle,&tag,128,0,NULL)) // The problem is here.. It doesn't write to the file..
ShowMessage("Error while writing file!"
CloseHandle(handle);
}
//--- end of code
One part of the problem, I think, is how to get 'number of bytes written' - in WriteFile, se appendix 2
Could it be so that I should change some attributes in CreateFile - se appendix 1 - or use another function to open the file, and if so should I use another function to write to the file??
There is also something that just crossed my mind, how do I delete the last 128 bytes in the file before I write the new ID3 tag?
The programs main function is to read the last 128 bytes of an .mp3 file where the ID3 tag is stored
If you got any other solution how to write to the end of a file I will gratefully accept them all
Thanks Martin....!!
//--- Appendix ---//
// Appendix 1 //--- found in Borland help files
HANDLE CreateFile(
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);
// Appendix 2 //--- allso found in Borland help files
BOOL WriteFile(
HANDLE hFile, // handle to file to write to
LPCVOID lpBuffer, // pointer to data to write to file
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
);
Martin G Broman
mgb_svea@hotmail.com
DWS - Alpha Whitin Dead Wolf Society