How to get the nodelist for a folder (related to shellbags)

0

I am writing a photo viewing application and I want the user to view photos in the same way he has them sorted and grouped on any folder the picture comes from. This led me to shellbags and with the help of nirsoft shellbagsview, I wrote some python code to do much of the work. The issue now is how to get the NodeList for a given folder. I looked into the BagMRU folder and cannot find a reference anywhere to a real folder. Can anyone please help me on how to get the NodeList id when given a folder name (say C:\myphotos). Many Thanks.

from winreg import *
from codecs import decode

folder_reg_path = "Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\Shell\\Bags\\1375\\Shell"
bags_mru_path = "Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU"



def get_sniffed_folder_type(reg_key):
    with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
        value = QueryValueEx(key, 'SniffedFolderType')
        return '%s' % (value[0])


def get_current_nodeid(reg_key):
    with OpenKey(HKEY_CURRENT_USER, reg_key, 0, KEY_READ) as key:
        #value = QueryValueEx(key, '0')
        #return value[0].hex().decode('utf-8')
        value = EnumValue(key, 2)
        return decode(value[1], 'ascii', 'ignore')


# which clsid should be used? the last one in the list
def get_current_clsid(reg_key):
    with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
        key_idx = 0
        value = None
        # keep looping until the last clsid entry is found
        while 1:
            try:
                temp = EnumKey(key, key_idx)
                key_idx += 1
                value = temp
            except:
                break
        return value


# the size of icons used by the folder
def get_folder_icon_size(reg_key):
    with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
        value = QueryValueEx(key, 'IconSize')
        return '%d pixels' % (value[0])

# the folder view. details, list, tiles e.t.c       
def get_logical_view_mode(reg_key):
    with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
        value = QueryValueEx(key, 'LogicalViewMode')
        logical_view_mode_dict = {1 : "Details view", 2 : "Tiles view", 3 : "Icons view", 4 : "List view", 5 : "Content view"}
        return logical_view_mode_dict[value[0]]


# folder view is based on view mode. so you can have a  logical view mode of icons view with a view mode of large icons for instance    
def get_folder_view_mode(reg_key):
    with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
        value = QueryValueEx(key, 'Mode')
        # view_mode 7 is only available on xp. A dead os
        view_mode_dict = {1 : "Medium icons", 2 : "Small icons", 3 : "List", 4 : "Details", 5 : "Thumbnail icons", 6 : "Large icons", 8 : "Content"}
        return view_mode_dict[value[0]]


# how is the folder being sorted
def get_folder_sort_by(reg_key):
    with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
        value = QueryValueEx(key, 'Sort')
        folder_sort_dict = {"0E000000" : "Date Modified", "10000000" : "Date Accessed", "0F000000" : "Date Created", "0B000000" : "Type", "0C000000" : "Size", "0A000000" : "Name", "02000000" : "Title", "05000000" : "Tags"}
        # we get a byte value which we will hexify and get a rather long string
        # similar to : 000000000000000000000000000000000100000030f125b7ef471a10a5f102608c9eebac0c000000ffffffff
        reg_value = value[0].hex()
        # now for this string, we need to get the last 16 strings. then we now get the first 8 out of it. so we will have
        folder_sort_dict_key = (reg_value[-16:][:8]).upper()
        #return folder_sort_dict[folder_sort_dict_key]
        print (reg_value)
        return folder_sort_dict_key

# in what order is the folder being sorted. ascending or descending???
def get_folder_sort_by_order(reg_key):
    with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
        value = QueryValueEx(key, 'Sort')
        folder_sort_dict = {"01000000" : "Ascending", "FFFFFFFF" : "Descending"}
        # we get a byte value which we will hexify and get a rather long string
        # similar to : 000000000000000000000000000000000100000030f125b7ef471a10a5f102608c9eebac0c000000ffffffff
        reg_value = value[0].hex()
        # now for this string, we need to get the last 16 strings. then we now get the last 8 out of it. so we will have
        folder_sort_dict_key = (reg_value[-16:][-8:]).upper()
        return folder_sort_dict[folder_sort_dict_key]

# How is the folder being grouped
def get_folder_group_by(reg_key):
    with OpenKey(HKEY_CURRENT_USER, reg_key) as key:
        value = QueryValueEx(key, 'GroupByKey:PID')
        folder_group_dict = {'10' : "Name", '14' : "Date Modified", '4*' : "Type", '12' : "Size", '15' : "Date Created", '5' : "Tags", '2' : "Title", '16' : "Date Accessed", '0' : "No Group Applied"}
        return folder_group_dict[str(value[0])]


# Registry is of the form:
# HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\1375\Shell\{5C4F28B5-F869-4E84-8E60-F11DB97C5CC7}
# where 1375 is a value called the NodeList, and {5C4F28B5-F869-4E84-8E60-F11DB97C5CC7} is a value under Shell chosen based on creation date

print ( 'The suggested folder type is %s' % get_sniffed_folder_type(folder_reg_path) )

# lets start by getting a value similar to {5C4F28B5-F869-4E84-8E60-F11DB97C5CC7} by finding the last child of folder_reg_path
folder_reg_path = folder_reg_path + '\\' + get_current_clsid(folder_reg_path)

print ( get_current_nodeid(bags_mru_path) )
print ( 'The registry path is %s' % (folder_reg_path) )
icon_size = get_folder_icon_size(folder_reg_path)
logical_view_mode = get_logical_view_mode(folder_reg_path)
view_mode = get_folder_view_mode(folder_reg_path)
sorted_by = get_folder_sort_by(folder_reg_path)
sorted_by_order = get_folder_sort_by_order(folder_reg_path)
folder_group_by = get_folder_group_by(folder_reg_path)
print ('The folder icon size is %s' % icon_size)
print('The folder logical view mode is %s' % logical_view_mode)
print('The folder view mode is %s' % view_mode)
print('The folder is sorted by %s in %s order' % (sorted_by, sorted_by_order))
print('The folder is grouped by: %s' % folder_group_by)

daibatzu

Posted 2019-06-03T23:03:19.907

Reputation: 101

No answers