Am 17/09/2011 20:51, schrieb John Paul Adrian Glaubitz:
As it seems that reading disc flags is generally missing in the current status of libnetmd i first made a small patch to implement this. But you are right. The key generation/exchange mechanism should go into libnetmd. Maybe we should provide something like netmd_start_session() and netmd_end_session() externally which set up and clean a secure session inside libnetmd.However, before we make any bigger changes to netmdcli/libnetmd, the code will need some further cleanup first. There is some code in netmdcli which I think should rather go into libnetmd. I was particularly thinking about the code which sets up the secure session and sends a track to the device. That should probably better go into libnetmd, so we avoid reinventing the wheel over and over again when using libnetmd in other applications. ... Adrian
Thomas
>From 8d5780c60f4694ce8468dd44e3bc684a09ad010d Mon Sep 17 00:00:00 2001 From: Thomas Arp <manner.moe@gmx.de> Date: Sun, 18 Sep 2011 16:25:00 +0200 Subject: [PATCH] integrate reading disc flags in netmd_initialize_disc_info() --- libnetmd/libnetmd.c | 25 +++++++++++++++++++++++++ libnetmd/libnetmd.h | 1 + netmdcli/netmdcli.c | 18 +++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletions(-) diff --git a/libnetmd/libnetmd.c b/libnetmd/libnetmd.c index 0291cbe..6d57ad1 100644 --- a/libnetmd/libnetmd.c +++ b/libnetmd/libnetmd.c @@ -131,6 +131,25 @@ static int request_disc_title(netmd_dev_handle* dev, char* buffer, size_t size) return (int)title_size - 25; } +int request_disc_flags(netmd_dev_handle* dev) +{ + int ret = -1; + unsigned char disc_flags_request[] = {0x00, 0x18, 0x06, 0x01, 0x10, 0x10, + 0x00, 0xff, 0x00, 0x00, 0x01, 0x00, + 0x0b }; + unsigned char flags[14]; + + ret = netmd_exch_message(dev, disc_flags_request, 0x0d, flags); + + if(ret < 0 || flags[7] != 0x10) + { + fprintf(stderr, "request_disc_flags: bad ret code\n"); + return 0; + } + + return flags[13] & 0xff; +} + int netmd_request_track_time(netmd_dev_handle* dev, const uint16_t track, struct netmd_track* buffer) { int ret = 0; @@ -329,6 +348,12 @@ int netmd_initialize_disc_info(netmd_dev_handle* devh, minidisc* md) set_group_data(md, 0, "<Untitled>", 0, 0); } + disc_flags = request_disc_flags(devh); + if (disc_flags & NETMD_DISC_FLAG_WRITE_PROTECTED) + md->writable = 0; + else + md->writable = 1; /* try to use disc as not write protected else if disc flags cannot be read */ + return disc_size; } diff --git a/libnetmd/libnetmd.h b/libnetmd/libnetmd.h index 52f7edb..2becb8e 100644 --- a/libnetmd/libnetmd.h +++ b/libnetmd/libnetmd.h @@ -81,6 +81,7 @@ typedef struct { size_t header_length; struct netmd_group *groups; unsigned int group_count; + int writable; } minidisc; diff --git a/netmdcli/netmdcli.c b/netmdcli/netmdcli.c index 60f1d81..ed43e8b 100644 --- a/netmdcli/netmdcli.c +++ b/netmdcli/netmdcli.c @@ -168,6 +168,13 @@ void retailmac(unsigned char *rootkey, unsigned char *hostnonce, gcry_cipher_close(handle2); } +static void cleanup(minidisc *md, netmd_dev_handle *devh, netmd_device *device_list) +{ + netmd_clean_disc_info(md); + netmd_close(devh); + netmd_clean(&device_list); +} + int main(int argc, char* argv[]) { netmd_dev_handle* devh; @@ -212,7 +219,8 @@ int main(int argc, char* argv[]) printf("%s\n", name); netmd_initialize_disc_info(devh, md); - printf("Disc Title: %s\n\n", md->groups[0].name); + printf("Disc Title: %s\n", md->groups[0].name); + printf("Protection status: %s\n\n", (md->writable ? "writable" : "write protected")); /* by default, log only errors */ netmd_set_log_level(NETMD_LOG_ERROR); @@ -441,6 +449,14 @@ int main(int argc, char* argv[]) unsigned char uuid[8] = { 0 }; unsigned char new_contentid[20] = { 0 }; + /* check if disc is write protected first */ + if(!md->writable) + { + printf("Cannot send track: disc is write protected\n"); + cleanup(md, devh, device_list); + return -1; + } + error = netmd_secure_leave_session(devh); puts(netmd_strerror(error)); -- 1.7.6.msysgit.0