示例#1
0
文件: libnetmd.c 项目: bobo1on1/netmd
int netmd_delete_group(usb_dev_handle* dev, minidisc* md, int group)
{
	int index = 0;
	struct netmd_group *p;
	
	/* check if requested group exists */
	if((group < 0) || (group > md->group_count))
		return -1;
	
	/* create a copy of groups below requested group */
	p = malloc(sizeof(struct netmd_group) * md->group_count);
	for(index = 0; index < group; index++)
	{
		p[index].name = strdup(md->groups[index].name);
		p[index].start = md->groups[index].start;
		p[index].finish = md->groups[index].finish;
	}
	
	/* copy groups above requested group */
	for(; index < md->group_count-1; index++)
	{
		p[index].name = strdup(md->groups[index+1].name);
		p[index].start = md->groups[index+1].start;
		p[index].finish = md->groups[index+1].finish;
	}

	/* free all memory, then make our copy the real info */
	netmd_clean_disc_info(md);
	md->groups = p;
	
	/* one less group now */
	md->group_count--;
	
	netmd_write_disc_header(dev, md);
	return 0;
}
示例#2
0
int main(int argc, char* argv[])
{
    netmd_dev_handle* devh;
    minidisc my_minidisc, *md = &my_minidisc;
    netmd_device *device_list, *netmd;
    unsigned int i = 0;
    unsigned int j = 0;
    char name[16];
    uint16_t track, playmode;
    int c;
    netmd_time time;
    netmd_error error;
    FILE *f;

    error = netmd_init(&device_list);
    if (error != NETMD_NO_ERROR) {
        printf("Error initializing netmd\n%s\n", netmd_strerror(error));
        return -1;
    }

    if (device_list == NULL) {
        puts("Found no NetMD device(s).");
        return -1;
    }

    /* pick first available device */
    netmd = device_list;

    error = netmd_open(netmd, &devh);
    if(error != NETMD_NO_ERROR)
    {
        printf("Error opening netmd\n%s\n", netmd_strerror(error));
        return -1;
    }

    error = netmd_get_devname(devh, name, 16);
    if (error != NETMD_NO_ERROR)
    {
        printf("Could not get device name\n%s\n", netmd_strerror(error));
        return -1;
    }
    printf("%s\n", name);

    netmd_initialize_disc_info(devh, md);
    printf("Disc Title: %s\n\n", md->groups[0].name);

    /* by default, log only errors */
    netmd_set_log_level(NETMD_LOG_ERROR);

    /* parse options */
    while (1) {
        c = getopt(argc, argv, "t");
        if (c == -1) {
            break;
        }
        switch (c) {
        case 't':
            netmd_set_log_level(NETMD_LOG_ALL);
            break;
        default:
            fprintf(stderr, "Unknown option '%c'\n", c);
            break;
        }
    }

    /* update argv and argc after parsing options */
    argv = &argv[optind - 1];
    argc -= (optind - 1);

    /* parse commands */
    if(argc > 1)
    {
        if(strcmp("rename", argv[1]) == 0)
        {
            i = strtoul(argv[2], NULL, 10);
            netmd_cache_toc(devh);
            netmd_set_title(devh, i & 0xffff, argv[3]);
            netmd_sync_toc(devh);
        }
        else if(strcmp("move", argv[1]) == 0)
        {
            i = strtoul(argv[2], NULL, 10);
            j = strtoul(argv[3], NULL, 10);
            netmd_move_track(devh, i & 0xffff, j & 0xffff);
        }
        else if(strcmp("groupmove", argv[1]) == 0)
        {
            i = strtoul(argv[2], NULL, 10);
            j = strtoul(argv[3], NULL, 10);
            netmd_move_group(devh, md, j & 0xffff, i & 0xffff);
        }
        else if(strcmp("write", argv[1]) == 0)
        {
            if(netmd_write_track(devh, argv[2]) < 0)
            {
                fprintf(stderr, "Error writing track %i\n", errno);
            }
        }
        else if(strcmp("newgroup", argv[1]) == 0)
        {
            netmd_create_group(devh, md, argv[2]);
        }
        else if(strcmp("settitle", argv[1]) == 0)
        {
            netmd_cache_toc(devh);
            netmd_set_disc_title(devh, argv[2], strlen(argv[2]));
            netmd_sync_toc(devh);
        }
        else if(strcmp("group", argv[1]) == 0)
        {
            i = strtoul(argv[2], NULL, 10);
            j = strtoul(argv[3], NULL, 10);
            if(!netmd_put_track_in_group(devh, md, i & 0xffff, j & 0xffff))
            {
                printf("Something screwy happened\n");
            }
        }
        else if(strcmp("retitle", argv[1]) == 0)
        {
            i = strtoul(argv[2], NULL, 10);
            netmd_set_group_title(devh, md, i, argv[3]);
        }
        else if(strcmp("play", argv[1]) == 0)
        {
            if( argc > 2 ) {
                i = strtoul(argv[2],NULL, 10);
                netmd_set_track( devh, i & 0xffff );
            }
            netmd_play(devh);
        }
        else if(strcmp("stop", argv[1]) == 0)
        {
            netmd_stop(devh);
        }
        else if(strcmp("pause", argv[1]) == 0)
        {
            netmd_pause(devh);
        }
        else if(strcmp("fforward", argv[1]) == 0)
        {
            netmd_fast_forward(devh);
        }
        else if(strcmp("rewind", argv[1]) == 0)
        {
            netmd_rewind(devh);
        }
        else if(strcmp("next", argv[1]) == 0)
        {
            netmd_track_next(devh);
        }
        else if(strcmp("previous", argv[1]) == 0)
        {
            netmd_track_previous(devh);
        }
        else if(strcmp("restart", argv[1]) == 0)
        {
            netmd_track_restart(devh);
        }
        else if(strcmp("settime", argv[1]) == 0)
        {
            track = strtoul(argv[2], (char **) NULL, 10) & 0xffff;
            if (argc > 6)
            {
                time.hour = strtoul(argv[3], (char **) NULL, 10) & 0xffff;
                time.minute = strtoul(argv[4], (char **) NULL, 10) & 0xff;
                time.second = strtoul(argv[5], (char **) NULL, 10) & 0xff;
                time.frame = strtoul(argv[6], (char **) NULL, 10) & 0xff;
            }
            else
            {
                time.hour = 0;
                time.minute = strtoul(argv[3], (char **) NULL, 10) & 0xff;
                time.second = strtoul(argv[4], (char **) NULL, 10) & 0xff;
                if (argc > 5)
                {
                    time.frame = strtoul(argv[5], (char **) NULL, 10) & 0xff;;
                }
                else
                {
                    time.frame = 0;
                }
            }

            netmd_set_time(devh, track, &time);
        }
        else if(strcmp("m3uimport", argv[1]) == 0)
        {
            import_m3u_playlist(devh, argv[2]);
        }
        else if(strcmp("delete", argv[1]) == 0)
        {
            i = strtoul(argv[2], NULL, 10);
            netmd_delete_track(devh, i & 0xffff);
        }
        else if(strcmp("deletegroup", argv[1]) == 0)
        {
            i = strtoul(argv[2], NULL, 10);
            netmd_delete_group(devh, md, i & 0xffff);
        }
        else if(strcmp("status", argv[1]) == 0) {
            print_current_track_info(devh);
        }
        else if (strcmp("raw", argv[1]) == 0) {
            send_raw_message(devh, argv[2]);
        }
        else if (strcmp("setplaymode", argv[1]) == 0) {
            playmode = 0;
            int i;
            for (i = 2; i < argc; i++) {
                if (strcmp(argv[i], "single") == 0) {
                    playmode |= NETMD_PLAYMODE_SINGLE;
                }
                else if (strcmp(argv[i], "repeat") == 0) {
                    playmode |= NETMD_PLAYMODE_REPEAT;
                }
                else if (strcmp(argv[i], "shuffle") == 0) {
                    playmode |= NETMD_PLAYMODE_SHUFFLE;
                }
            }
            printf("%x\n", playmode);
            netmd_set_playmode(devh, playmode);
        }
        else if (strcmp("capacity", argv[1]) == 0) {
            netmd_disc_capacity capacity;
            netmd_get_disc_capacity(devh, &capacity);

            printf("Recorded:  ");
            print_time(&capacity.recorded);
            printf("\nTotal:     ");
            print_time(&capacity.total);
            printf("\nAvailable: ");
            print_time(&capacity.available);
            printf("\n");
        }
        else if (strcmp("recv", argv[1]) == 0) {
            i = strtoul(argv[2], NULL, 10);
            f = fopen(argv[3], "wb");
            netmd_secure_recv_track(devh, i & 0xffff, f);
            fclose(f);
        }
        else if (strcmp("send", argv[1]) == 0) {
            netmd_error error;
            netmd_ekb ekb;
            unsigned char chain[] = {0x25, 0x45, 0x06, 0x4d, 0xea, 0xca,
                                     0x14, 0xf9, 0x96, 0xbd, 0xc8, 0xa4,
                                     0x06, 0xc2, 0x2b, 0x81, 0x49, 0xba,
                                     0xf0, 0xdf, 0x26, 0x9d, 0xb7, 0x1d,
                                     0x49, 0xba, 0xf0, 0xdf, 0x26, 0x9d,
                                     0xb7, 0x1d};
            unsigned char signature[] = {0xe8, 0xef, 0x73, 0x45, 0x8d, 0x5b,
                                         0x8b, 0xf8, 0xe8, 0xef, 0x73, 0x45,
                                         0x8d, 0x5b, 0x8b, 0xf8, 0x38, 0x5b,
                                         0x49, 0x36, 0x7b, 0x42, 0x0c, 0x58};
            unsigned char rootkey[] = {0x13, 0x37, 0x13, 0x37, 0x13, 0x37,
                                       0x13, 0x37, 0x13, 0x37, 0x13, 0x37,
                                       0x13, 0x37, 0x13, 0x37};
            netmd_keychain *keychain;
            netmd_keychain *next;
            size_t done;
            unsigned char hostnonce[8] = { 0 };
            unsigned char devnonce[8] = { 0 };
            unsigned char sessionkey[8] = { 0 };
            unsigned char kek[] = { 0x14, 0xe3, 0x83, 0x4e, 0xe2, 0xd3, 0xcc, 0xa5 };
            unsigned char contentid[] = { 0x01, 0x0F, 0x50, 0x00, 0x00, 0x04,
                                          0x00, 0x00, 0x00, 0x48, 0xA2, 0x8D,
                                          0x3E, 0x1A, 0x3B, 0x0C, 0x44, 0xAF,
                                          0x2f, 0xa0 };
            netmd_track_packets *packets = NULL;
            size_t packet_count = 0;
            struct stat stat_buf;
            unsigned char *data;
            size_t data_size;

            uint16_t track;
            unsigned char uuid[8] = { 0 };
            unsigned char new_contentid[20] = { 0 };

            error = netmd_secure_leave_session(devh);
            puts(netmd_strerror(error));

            error = netmd_secure_set_track_protection(devh, 0x01);
            puts(netmd_strerror(error));

            error = netmd_secure_enter_session(devh);
            puts(netmd_strerror(error));

            /* build ekb */
            ekb.id = 0x26422642;
            ekb.depth = 9;
            ekb.signature = malloc(sizeof(signature));
            memcpy(ekb.signature, signature, sizeof(signature));

            /* build ekb key chain */
            ekb.chain = NULL;
            for (done = 0; done < sizeof(chain); done+=16U)
            {
                next = malloc(sizeof(netmd_keychain));
                if (ekb.chain == NULL) {
                    ekb.chain = next;
                }
                else {
                    keychain->next = next;
                }
                next->next = NULL;

                next->key = malloc(16);
                memcpy(next->key, chain + done, 16);

                keychain = next;
            }

            error = netmd_secure_send_key_data(devh, &ekb);
            puts(netmd_strerror(error));

            /* cleanup */
            free(ekb.signature);
            keychain = ekb.chain;
            while (keychain != NULL) {
                next = keychain->next;
                free(keychain->key);
                free(keychain);
                keychain = next;
            }

            /* exchange nonces */
            gcry_create_nonce(hostnonce, sizeof(hostnonce));
            error = netmd_secure_session_key_exchange(devh, hostnonce, devnonce);
            puts(netmd_strerror(error));

            /* calculate session key */
            retailmac(rootkey, hostnonce, devnonce, sessionkey);

            error = netmd_secure_setup_download(devh, contentid, kek, sessionkey);
            puts(netmd_strerror(error));

            /* read source */
            stat(argv[2], &stat_buf);
            data_size = (size_t)stat_buf.st_size;
            data = malloc(data_size);
            f = fopen(argv[2], "rb");
            fseek(f, 60, SEEK_CUR);
            fread(data, data_size - 60, 1, f);
            fclose(f);
            error = netmd_prepare_packets(data, data_size-60, &packets, &packet_count, kek);
            puts(netmd_strerror(error));

            /* send to device */
            error = netmd_secure_send_track(devh, NETMD_WIREFORMAT_LP2,
                                            NETMD_DISKFORMAT_LP2,
                                            (data_size - 60) / 192, packets,
                                            packet_count, sessionkey,
                                            &track, uuid, new_contentid);
            puts(netmd_strerror(error));

            /* cleanup */
            netmd_cleanup_packets(&packets);

            /* set title */
            netmd_log(NETMD_LOG_DEBUG, "New Track: %d\n", track);
            netmd_cache_toc(devh);
            netmd_set_title(devh, track, "test");
            netmd_sync_toc(devh);

            /* commit track */
            error = netmd_secure_commit_track(devh, track, sessionkey);
            puts(netmd_strerror(error));

            /* forget key */
            error = netmd_secure_session_key_forget(devh);
            puts(netmd_strerror(error));

            /* leave session */
            error = netmd_secure_leave_session(devh);
            puts(netmd_strerror(error));
        }
        else if(strcmp("help", argv[1]) == 0)
        {
            print_syntax();
        }
        else
        {
            print_disc_info(devh, md);
            print_syntax();
        }
    }
    else
        print_disc_info(devh, md);

    netmd_clean_disc_info(md);
    netmd_close(devh);
    netmd_clean(&device_list);

    return 0;
}
示例#3
0
文件: libnetmd.c 项目: bobo1on1/netmd
int netmd_move_group(usb_dev_handle* dev, minidisc* md, int track, int group)
{
	int index = 0;
	int i = 0;
	int gs = 0;
 	struct netmd_group store1;
	struct netmd_group *p, *p2;
	int gt = md->groups[group].start;
	int finish = (md->groups[group].finish - md->groups[group].start) + track;
	
	p = p2 = 0;

	// empty groups can't be in front
	if(gt == 0)
		return -1;

	/* loop, moving tracks to new positions */
	for(index = track; index <= finish; index++, gt++)
	{
		printf("Moving track %i to %i\n", (gt - 1), index);
		netmd_move_track(dev, (gt -1), index);
	}
	md->groups[group].start = track + 1;
	md->groups[group].finish = index;

	/* create a copy of groups */
	p = malloc(sizeof(struct netmd_group) * md->group_count);
	for(index = 0; index < md->group_count; index++)
	{
		p[index].name = malloc(strlen(md->groups[index].name) + 1);
		strcpy(p[index].name, md->groups[index].name);
		p[index].start = md->groups[index].start;
		p[index].finish = md->groups[index].finish;
	}

	store1 = p[group];
	gs = store1.finish - store1.start + 1; /* how many tracks got moved? */

	/* find group to bump */
	if(track < md->groups[group].start)
	{
		for(index = 0; index < md->group_count; index++)
		{
			if(md->groups[index].start > track)
			{
				for(i = group - 1; i >= index; i--)
				{
					/* all tracks get moved gs spots */
					p[i].start += gs;

					if(p[i].finish != 0)
						p[i].finish += gs;

					p[i + 1] = p[i]; /* bump group down the list */
				}

				p[index] = store1;
				break;
			}
			else
			{
				if((group + 1) < md->group_count)
				{
					for(i = group + 1; i < md->group_count; i++)
					{
						/* all tracks get moved gs spots */
						p[i].start -= gs;

						if(p[i].finish != 0)
							p[i].finish -= gs;

						p[i - 1] = p[i]; /* bump group down the list */
					}

					p[index] = store1;
					break;
				}
			}
		}
	}

	/* free all memory, then make our copy the real info */
	netmd_clean_disc_info(md);
	md->groups = p;

	netmd_write_disc_header(dev, md);
	return 0;
}